If I make a simple Xcode project in cocos2d I've always wondered what happens in the following situation:
Method A is scheduled every 0.01 seconds
Method B is scheduled every 1 second
Now suppose method B is a large method and takes a moment to compute. Will it EVER be interrupted by method A?
In other words, will a method always complete before another one starts?
I havn't created threads or anything.
In general, when you're scheduling stuff in the UI thread of a UI application, once a specific operation is started, it's not interrupted (except for errors). This holds not only for iOS, but for most UI platforms.
The system may interrupt the UI thread to handle hardware interrupts (or, eg, interrupts due to received cell signals), but those interruptions would be (mostly) "transparent" to the application.
But you'll never be interrupted by your own operations.
This assumes you would be using, say, an NSTimer to schedule your methods AND both methods will be processing on the same runloop (i.e. not using seperate threads per method which is typically done when you want to schedule two methods to run independantly).
This quote taken directly from the NSTimer class reference overview section on apple's site:
If a timer’s firing time occurs during a long callout or while the run loop is in a mode that is not monitoring the timer, the timer does
not fire until the next time the run loop checks the timer.
Therefore, the actual time at which the timer fires potentially can be
a significant period of time after the scheduled firing time.
That is to say that Method A's polling mechanism (NSTimer for example) will not fire until Method B has completed assuming they are on the same run loop. Method A would not interrupt Method B, per sé, but is dependent on it completing its task.
If you want information on placing Method A and Method B on separate thread so they work independently, you can start here: Grand Central Dispatch
If you are not using threads, your methods are guaranteed to be executed sequentially, without interruptions.
Related
I am struggling to understand the key differences between DispatchSourceTimer, Timer and asyncAfter (in my case for scheduling a task that needs to be ran every X seconds, although understanding the differences in timers can be useful to) (Or is there another (more efficient) scheduling mechanism in Swift besides the listed timers?).
A Timer needs an active run loop on the current queue it was started on. A DispatchSourceTimer does not need that. A Timer keeps the CPU from going into the idle state. Does this apply to DispatchSourceTimer/asyncAfter as well?
In what situation a Timer is preferred over a DispatchSourceTimer/asyncAfter? And of course the difference between all of them?
I want to schedule work every 15 seconds in my application on a private queue. This means I have to use DispatchSourceTimer because I am on a queue that is not the main thread (or add a runloop to the queue and use Timer). However, I do not see any benefit of even using a Timer in the first place. Maybe there is another operation that I can use that schedule work every X seconds on a private queue that is more efficient than a DispatchSourceTimer, but I did not came across a better solution.
Is a DispatchSourceTimer more efficient than a Timer? Or should I go on a self-calling method with asyncAfter?
This is the code to create the timers.
asyncAfter
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(2)) {
// Code
}
Timer
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (_) in
// Code
}
DispatchSourceTimer
let timer = DispatchSource.makeTimerSource()
timer.schedule(deadline: .now() + .seconds(1))
timer.setEventHandler {
// Code
}
timer.activate()
Whats are the cons and pros of all the timers? When should I use one above the other? What timer way is the most efficient? I came up with the following:
Timer
Pros:
Can be invalidated
No reference needed
Can be stopped while it is scheduled.
Cons:
Prevents CPU to go idle
Needs to be run on a queue with a run loop (else nothing happens, even no assertion trigger...)
DispatchSourceTimer
Pros:
Can be cancelled
No run loop needed
Cons:
Needs a strong reference else it gets deallocated instantly
asyncAfter
Pros:
- No run loop needed
Cons:
- Can not be cancelled (I think)
Are there even more timers? Why are there so many timers? I expected some real difference across all the different timers, but I couldn't find them.
Alot of questions here as you can read. The main question is: what timers are available and what timers should I use in what case and why?
Timer is a Swift bridge of NSTimer, which goes back to NeXTSTEP, long, long before Grand Central Dispatch (GCD) and things like DispatchSourceTimer, which didn't come along until 10.6 (in the form of dispatch_source_set_timer) and dispatchAfter (in the form of dispatch_after).
NSTimer is based on the run loop, which was the primary way that concurrency was done until GCD. It's a cooperative concurrency system, designed primary to run on a single thread on a single core (though it can be expanded to multi-threaded environments).
While the run loop is still very important in Cocoa, it is no longer the primary, or even preferred, way to manage concurrency. Since 10.6, GCD has been the increasingly preferred approach (though adding a block-based NSTimer API in the 10.12 timeframe was a welcome modernization).
On the scale of 15 seconds, the efficiency differences are pretty irrelevant. That said, I don't understand your comment "A Timer keeps the CPU from going into the idle state." I don't believe that's true. The CPU will definitely still go into the idle state when waiting on an NSTimer to fire.
I would not set up a run loop just to run an NSTimer. You would be much better off scheduling it on the main runloop and then using DispatchQueue.async to do the actual work on some other queue.
As a broad rule, I use the highest-level tool that meets the need. Those are the ones that Apple is likely to optimize the best over time with me making the fewest changes. For example, NSTimer fire dates are automatically adjusted to improve energy efficiency. With DispatchSourceTimer, you get control over the leeway setting to get the same benefit, but it's up to you to set it (the default is zero, which has the worst energy impact). Of course, the reverse is also true. DispatchSourceTimer is the lowest level and gives you the most control, so if that's what you need, that's the one to use.
For your example, I'd personally probably use a Timer and just dispatch to the private queue as part of the block. But a DispatchSourceTimer would be completely appropriate.
asyncAfter is really a different thing, since it's always a one-shot. That's great if you want a one-shot, but it changes things if you want to repeat. If you just call asyncAfter in the block to repeat, it's going to be 15 seconds after the last time you finished, rather than being spaced 15 seconds apart. The former will tend to drift a bit late over time. The design question is this: if for some reason your task took 5 seconds to complete, would you want the next fire event to happen 15 seconds from the end of that, or would you want a constant 15 seconds between each fire event? Your choice there will determine which tool is correct.
As a slight note there, NSTimer events are always a little later than they are scheduled. GCD events with a leeway setting can be a little early or a little late. As a practical matter, there's no such thing as being "on time" (that's a period of zero length; you're not going to hit it). So the question is always whether you are promised to be late like NSTimer, or you might be early like GCD with leeway.
Have been trying to google this but getting a bit stuck.
Let's say we have a class that fires an event, and that event could be fired by several threads at the same time.
Using Observable.FromEventPattern, we create an Observable, and subscribe to that event. How exactly does Rx manage multiple those events being fired at once? Let's say we have 3 events fired in quick succession on different threads. Does it queue them internally, and then call the Subscribe delegate synchronously for each one? Let's say we were subscribing on a thread pool, can we still guarantee the Subscriptions would be processed separately in time?
Following on from that, let's say for each event, we want to perform an action, but it's a method that's potentially not thread safe, so we only want one thread to be in this method at a time. Now I see we can use an EventLoop Scheduler, and presumably we wouldn't need to implement any locking on the code?
Also, would observing on the Current Thread be an option? Is Current Thread the thread that the event was fired from, or the event the subscription was set up on? i.e. Is that current thread guaranteed to always be the same or could be have 2 threads running ending up in the method at the same time?
Thx
PS: I put an example together but I always seem to end up on the samethread in my subscrive method, even when I ObserveOn the threadpool, which is confusing :S
PSS: From doing a few more experiments, it seems that if no Schedulers are specified, then RX will just execute on whatever thread the event was fired on, meaning it processes several concurrently. As soon as I introduce a scheduler, it always runs things consecutively, no matter what the type of the scheduler is. Strange :S
According to the Rx Design Guidelines, an observable should never call OnNext of an observer concurrently. It will always wait for the current call to complete before making the next call. All Rx methods honor this convention. And, more importantly, they assume you also honor this convention. When you violate this condition, you may encounter subtle bugs in the behavior of your Observable.
For those times when you have source data that does not honor this convention (ie it can produce data concurrently), they provide Synchronize.
Observable.FromEventPattern assumes you will not be firing concurrent events and so does nothing to prevent concurrent downstream notifications. If you plan on firing events from multiple threads, sometimes concurrently, then use Synchronize() as the first operation you do after FromEventPattern:
// this will get you in trouble if your event source might fire events concurrently.
var events = Observable.FromEventPattern(...).Select(...).GroupBy(...);
// this version will protect you in that case.
var events = Observable.FromEventPattern(...).Synchronize().Select(...).GroupBy(...);
Now all of the downstream operators (and eventually your observer) are protected from concurrent notifications, as promised by the Rx Design Guidelines. Synchronize works by using a simple mutex (aka the lock statement). There is no fancy queueing or anything. If one thread attempts to raise an event while another thread is already raising it, the 2nd thread will block until the first thread finishes.
In addition to the recommendation to use Synchronize, it's probably worth having a read of the Intro to Rx section on scheduling and threading. It Covers the different schedulers and their relationship to threads, as well as the differences between ObserveOn and SubscribeOn, etc.
If you have several producers then there are RX methods for combining them in a threadsafe way
For combining streams of the same type of event into a single stream
Observable.Merge
For combining stream of different types of events into a single stream using a selector to transform the latest value on each stream into a new value.
Observable.CombineLatest
For example combining stock prices from different sources
IObservable<StockPrice> source0;
IObservable<StockPrice> source1;
IObservable<StockPrice> combinedSources = source0.Merge(source1);
or create balloons at the current position every time there is a click
IObservable<ClickEvent> clicks;
IObservable<Position> position;
IObservable<Balloons> balloons = clicks
.CombineLatest
( positions
, (click,position)=>new Balloon(position.X, position.Y)
);
To make this specifically relevant to your question you say there is a class which combines events from different threads. Then I would use Observable.Merge to combine the individual event sources and expose that as an Observable on your main class.
BTW if your threads are actually tasks that are firing events to say they have completed here is an interesting patterns
IObservable<Job> jobSource;
IObservable<IObservable<JobResult>> resultTasks = jobSource
.Select(job=>Observable.FromAsync(cancelationToken=>DoJob(token,job)));
IObservable<JobResult> results = resultTasks.Merge();
Where what is happening is you are getting a stream of jobs in. From the jobs you are creating a stream of asynchronous tasks ( not running yet ). Merge then runs the tasks and collects the results. It is an example of a mapreduce algorithm. The cancellation token can be used to cancel running async tasks if the observable is unsubscribed from (ie canceled )
I have an application which uses some external library for analytics. Problem is that I suspect it does some things synchronously, which blocks my thread and makes watchdog kill my app after 10 secs (0x8badf00d code). It is really hard to reproduce (I cannot), but there are quite few cases "in the wild".
I've read some documentation, which suggested that instead creating another thread I should use run-loops. Unfortunately the more I read about them, the more confused I get. And the last thing i want to do is release a fix which will break even more things :/
What I am trying to achieve is:
From main thread add a task to the run-loop, which calls just one function: initMyAnalytics(). My thread continues running, even if initMyAnalytics() gets locked waiting for network data. After initMyAnalytics() finishes, it quietly quits and never gets called again (so it doesnt loop or anything).
Any ideas how to achieve it? Code examples are welcome ;)
Regards!
You don't need to use a run loop in that case. Run loops' purpose is to proceed events from various sources sequentially in a particular thread and stay idle when they have nothing to do. Of course, you can detach a thread, create a run loop, add a source for your function and run the run loop until the function ends. The same as you can use a semi-trailer truck to carry your groceries home.
Here, what you need are dispatch queues. Dispatch queues are First-In-First-Out data structures that run tasks asynchronously. In contrary to run loops, a dispatch queue isn't tied to a particular thread: the working threads are automatically created and terminated as and when required.
As you only have one task to execute, you don't need to create a dispatch queue. Instead you will use an existing global concurrent queue. A concurrent queue execute one or more tasks concurrently, which is perfectly fine in our case. But if we had many tasks to execute and wanted each task to wait for its predecessor to end, we would need to create a serial queue.
So all you have to do is:
create a task for your function by enclosing it into a Block
get a global queue using dispatch_get_global_queue
add the task to the queue using dispatch_async.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
initMyAnalytics();
});
DISPATCH_QUEUE_PRIORITY_DEFAULT is a macro that evaluates to 0. You can get different global queues with different priorities. The second parameter is reserved for future use and should always be 0.
Can any body explain me what is the difference among sleep() , usleep() & [NSThread sleepForTimeInterval:] ?
What is the best condition to use these methods ?
sleep(3) is a posix standard library method that attempts to suspend the calling thread for the amount of time specified in seconds. usleep(3) does the same, except it takes a time in microseconds instead. Both are actually implemented with the nanosleep(2) system call.
The last method does the same thing except that it is part of the Foundation framework rather than being a C library call. It takes an NSTimeInterval that represents the amount of time to be slept as a double indicating seconds and fractions of a second.
For all intents and purposes, they all do functionally the same thing, i.e., attempt to suspend the calling thread for some specified amount of time.
What is the best condition to use
these methods ?
Never
Or, really, pretty much almost assuredly never ever outside of the most unique of circumstances.
What are you trying to do?
On most OSs, sleep(0) and its variants can be used to improve efficiency in a polling situation to give other threads a chance to work until the thread scheduler decides to wake up the polling thread. It beats a full-on while loop. I haven't found much use for a non-zero timeout though, and apple in particular has done a pretty good job of building an event driven architecture that should eliminate the need for polling in most situations anyway.
-Example usage of sleep is in the following state:
In network simulation scenario, we usually have events that are executed event by event,using a scheduler. The scheduler executes events in orderly fashion.
When an event is finished executing, and the scheduler moves to the next event, the scheduler compares the next event execution time with the machine clock. If the next event is scheduled for a future time, the simulator sleeps until that realtime is reached and then executes the next event.
-From linux Man pages:
The usleep() function suspends execution of the calling thread for (at least) usec microseconds. The sleep may be lengthened slightly by any system activity or by the time spent processing the call or by the granularity of system timers.
while sleep is delaying the execution of a task(could be a thread or anything) for sometime .Refer to 1 and 2 for more details about the functions.
Say I have two NSTimers in my iPhone app: timer1 and timer2. timer1 calls function1 30 times per second and timer2 calls function2 30 times per second. Assume these two functions are reading and updating the same integer variables. Are there any "multi-threading" issues here? If not how does iPhone OS handle the execution of the two functions (in general)?
The core of any iPhone application (and some other platforms) is a run loop. Each thread may have a run loop, and the run loop on the main thread is set up for you. When there is something to do, like fire an NSTimer or draw the view hierarchy, the run loop performs those tasks. When there is nothing to do, the run loop is idle, allowing other things to process.
The run loop internals are thread aware so that nothing handled by the run loop has to be. All the NSTimer callbacks and view rendering happens on a single thread in a serial or linear flow.
For specific details, you can look up NSRunLoop or CFRunLoop.
As far as I'm aware, NSTimers use the run loop to achieve their 'asynchronosity'. If the timer is created using the scheduledTimerWith... method then it will be scheduled on the default (main) run loop and will be executed on the main thread.
I don't think any new threads are created for the timer (unless you do it explicitly, and assign the timer to that run loop).
So in the end, I believe your two timers shouldn't conflict with each other.
However, the documentation states that timers don't represent real time. The timer will fire on or after the scheduled time, but is not guaranteed to fire exactly at the scheduled time. Therefore if the fired method takes longer to execute than the interval of the timer, you may not see the method called as often as you'd expect.
With that said, is there any particular reason you're asking the question? Are you seeing undesired behaviour using this setup?