I want to know if blocks in c / cocoa run on a seperate thread to the main thread. Would they be useful for executing computationally expensive code while leaving the UI responsive?
Blocks are just snippets of code bundled up into a callable object. How they run is entirely up to the code that calls it.
Running blocks on a separate thread is not only possible, but is precisely the reason the blocks concept was introduced. It exists to support Grand Central Dispatch, which hides a lot of the complexity of concurrent programming behind a task-oriented model.
They don't have to run on another thread, but they can. You can schedule them on NSOperationQueues or GCD queues, and those queues can be drained by background threads.
And yes, this can be a useful construct to help you get time consuming work off the main thread. But that's not all that blocks are useful for, and conversely you can do background processing with or without blocks.
You can use GCD to schedule blocks for issuing on other threads. The two were introduced together, so any discussion of the one usually mentions the other. However, blocks are not in themselves inherently a multithreading mechanism.
Related
As new to Kotlin, I am facing a little problem in understanding the difference between thread and coroutine. Can someone make it simple to understand the fundamental them of them?
I started learning core concepts of Kotlin programing language recently, but I got stuck in differentiating threads and coroutines.
Threads are native mechanisms, whereas coroutines are user-level abstractions, which use threads and actually make better use of them.
Key differences I can point out:
Thread is a different mechanism, which is linked to the native thread
of OS. This is the reason why creating hundreds/thousands of threads
is impossible - thread consumes a lot of OS' memory. Coroutine is a
user-level abstraction of some worker which does not use excessive
amount of memory, since it is not linked to native resources and use
resources of JVM heap.
Thread gets blocked instead of suspending and dispatching the job to
another thread.
Thread cannot be used until its work completes.
Coroutine is a user-friendly abstraction which allows you to reuse thread's resources to execute suspending functions. Mechanism is following: suspending function is called from a coroutine and dispatched on a specific thread. While it suspends, thread resources can be used to execute another suspending function.
To get better understanding of how coroutines work in combination with threads, you can read my answer to my own question, which is also a source for this answer.
I have an iOS application using NSThreads for concurrency tasks. I will try to migrate it to be using the Grand Central Dispatch (GCD) for handling concurrency.
The problem is that the app needs information regarding how many threads has been created since a given time. And how many threads that was spawned since that given time is currently running.
At the moment this is done by creating a category that does a method swizzling on the -main method in NSThread. In the new swizzled method it simply increments the total number of threads running and then decrement the same variable before the new swizzled -main method returns.
The problem is that when I use GCD dispatch_async it does not create a NSThread, hence my category approach does not work. How can I achieve the same while using GCD to handle concurrency?
What I would like to detect is when a new block is added to GCD, and when that block has been executed.
Any suggestions on how to achieve the same is very welcome.
EDIT
Many thanks to #ipmcc and #RyanR for helping me out on this. :) I believe I need to tell some more about the background and what I am trying to accomplish.
What I am actually trying is to extend the iOS testing framework Frank. Frank embeds a small web-server within a given app which enables sending HTTP request to the iOS application and thereby simulating events, a swipe or a tap gesture as an example.
I would like to extend it in a way that enables it to wait until all work triggered by a specific simulated event has ended before returning upon a request.
However I found it hard to detect exactly what work was triggered by the received event. And thats how I came to the solution to just reset a thread counter and then increment this counter for all created threads after the event was simulated, and decrement it when the threads are finishing. And then block until threads count became zero again. I know this approach is not perfect either, and it wont work with GCP.
Is there any other way to achieve it? Another possible solution which I have thought of is to specify that everything must run synchronized except the thread handling the HTTP request. However I don't know if this possible.
Any suggestions on how to achieve blocking after each simulated event until work triggered by that event has completed?
The problem is that the app needs information regarding how many
threads has been created since a given time. And how many threads that
was spawned since that given time is currently running.
You will not be able to get this information from GCD. One of the points of GCD is that you do not manage the thread pool. It is opaque. You'll note that even pthreads, the underlying threading library on which NSThread and GCD are built, does not have a (public) means to enumerate all existing threads or get the number of running threads. This is not going to be doable without hard core low level hackery. If you need to control or know the number of threads, then you need to be the one to spawn and manage them, and GCD is the wrong abstraction for you.
At the moment this is done by creating a category that does a method
swizzling on the -main method in NSThread. In the new swizzled method
it simply increments the total number of threads running and then
decrement the same variable before the new swizzled -main method
returns.
Note that this only tells you the number of threads started using NSThread. As mentioned, NSThread is a fairly high level abstraction on top of pthreads. There is nothing to prevent library code from spawning its own threads using the pthreads API that will be invisible to your count.
The problem is that when I use GCD dispatch_async it does not create a
NSThread, hence my category approach does not work. How can I achieve
the same while using GCD to handle concurrency?
In short, you can't. If you want to go forth and patch functions all over the various frameworks, then you should look up a library called mach_override. (But please don't.)
What I would like to detect is when a new block is added to GCD, and
when that block has been executed.
Since GCD uses thread pools, the act of adding a block does not imply a new thread. (And that's sorta the whole point.)
If you have some limited resource whose consumption you need to manage, the traditional way to do that would be with a limiting semaphore, but that is just one option.
This whole question just reeks of a poor design. Like the number of pthreads, GCD's queue widths are opaque/non-public. Your previous solution was not particularly viable (as discussed), and further efforts are likely to yield similarly poor solutions. You should really rethink your architecture such that knowing how many threads are running isn't important.
EDIT: Thanks for the clarification. There's not really a generic way, from the outside, to tell when all the "work" is done. What if an action sets up a timer that won't call back for ten minutes? At the extreme, consider this: the main runloop continues to spin for the entire life of the app, and as long as the main runloop is spinning, "work" could be being done on it.
In order to detect "doneness" your app has to signal doneness. In order to signal doneness, the app has to have some way (internal to itself) to know it's done. Put differently, the app can't tell something else (i.e. Frank) something it doesn't know. One way to go about this would be to encapsulate all the work you do in your app in NSOperations. NSOperation/NSOperationQueue provide good ways of reporting "doneness." At the simplest level, you could wrap the code where you kickoff work in an NSBlockOperation, then add a completion block to that operation that signals something else when it's done, and enqueue it to an NSOperationQueue for execution. (You could also do this with dispatch_group and dispatch_group_notify if you prefer working in the GCD style.)
If you have specific questions about how to package up your app's work into NSOperations, I would suggest starting a new question.
You can hook into the dispatch introspection functions (introspection.h, methods all start with dispatch_introspection), but you have to link with that library which is supposed to be only for debugging. I don't think you can include that in a release build. Your best bet would be to encapsulate GCD into your own object, so all your code submits blocks to execute through that object and it submits them to GCD after tracking whatever you're interested in. You won't be able to track thread consumption though, because GCD intentionally abstracts that and reuses threads.
I am adding objects to the same NSMutableDictionary from several different blocks in Objective-C. These blocks are all callback functions for some other process; that is, they will be called at some undetermined point in the future when the original process has finished.
My concern has to do with possibility of the NSMutableDictionary being operated on by two different blocks at the same time. I know that if the two blocks are run on different threads, then this is a legitimate concern. I just want to know if blocks are always run on different threads, making this a concern whenever I use blocks at all.
No, blocks are not always run on different threads. It depends entirely on what the block is and how you schedule it to be executed. Are you executing it yourself, adding it to an operation queue, using a GCD queue. The block could be run on any thread, including the main thread. You have control over whether it is run on the main thread or a background thread.
ThreadSafety
Apple's Grand Central Dispatch reference says:
"...if your application needs to operate at the Unix level of the
system—for example, if it needs to manipulate file descriptors, Mach
ports, signals, or timers. GCD is not restricted to system-level
applications, but before you use it for higher-level applications, you
should consider whether similar functionality provided in Cocoa (via
NSOperation and block objects) would be easier to use or more
appropriate for your needs.".
http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
I can't actually think of situations, for high-level applications, in which the use of GCD is mandatory and NSOperation could/should not be used.
Any thoughts?
The point being made here is the same one that Chris Hanson states in his article "When to use NSOperation vs. GCD":
The straightforward answer is a general guideline for all application
development:
Always use the highest-level abstraction available to you, and drop
down to lower-level abstractions when measurement shows that they are
needed.
In this particular case, it means that when writing Cocoa
applications, you should generally be using NSOperation rather than
using GCD directly. Not because of a difference in efficiency, but
because NSOperation provides a higher-level abstraction atop the
mechanisms of GCD.
In general, I agree with this. NSOperation and NSOperationQueue provide support for dependencies and one or two other things that GCD blocks and queues don't have, and they abstract away the lower-level details of how the concurrent operations are implemented. If you need that functionality, NSOperation is a very good way to go.
However, after working with both, I've found myself replacing all of my NSOperation-based code with GCD blocks and queues. I've done this for two reasons: there is significant overhead when using NSOperation for frequent actions, and I believe my code is cleaner and more descriptive when using GCD blocks.
The first reason comes from profiling in my applications, where I found that the NSOperation object allocation and deallocation process took a significant amount of CPU resources when dealing with small and frequent actions, like rendering an OpenGL ES frame to the screen. GCD blocks completely eliminated that overhead, leading to significant performance improvements.
The second reason is more subjective, but I believe that my code is cleaner when using blocks than NSOperations. The quick capture of scope allowed by a block and the inline nature of them make for less code, because you don't need to create custom NSOperation subclasses or bundle up parameters to be passed into the operation, and more descriptive code in my opinion, because you can place the code to be run in a queue at the point where it is fired off.
Again, its a matter of preference, but I've found myself using GCD more, even in otherwise more abstracted Cocoa applications.
Prefer GCD where task is not much complex and optimum CPU performance is required.
Prefer NSOperationQueue where task is complex and requires canceling or suspending a block and dependency management.
GCD is a lightweight way to represent units of work that are going to be executed concurrently. You don’t schedule these units of work; the system takes care of scheduling for you. Adding dependency among blocks can be a headache. Canceling or suspending a block creates extra work for you as a developer!
NSOperation and NSOperationQueue add a little extra overhead compared to GCD, but you can add dependency among various operations. You can re-use, cancel or suspend operations. NSOperation is compatible with Key-Value Observation (KVO); for example, you can have an NSOperation start running by listening to NSNotificationCenter.
For detailed explanation, refer this question: NSOperation vs Grand Central Dispatch
Well, NSOperation has no equivalents to dispatch_source_t, dispatch_io, dispatch_data_t, dispatch_semaphore_t, etc... It's also somewhat higher overhead.
On the flip side, libdispatch has no equivalents to operation dependencies, operation priorities (queue priorities are somewhat different), or KVO on operations.
There are two things that NSOperationQueue can do that GCD doesn't do: The minor one is dependencies (add an operation to a queue but tell it to only execute when certain other operations are finished), and the big one is that NSOperation gives you an object which can receive messages while the task is executing, unlike GCD which has blocks that cannot receive messages except in a very limited way. You either need these two features, or you don't. If you don't, using GCD is just an awful lot easier to use.
That's why useful examples of NSOperation are always quite complex. If they were easy, you would use GCD instead. You usually create a subclass of NSOperation, which will be some significant amount of work, or use one that someone else has created.
I've actually just been reading 'round about this, and, I'm sure it will come as know surprise, opinions differ.
I can't think of a case where you'd have to use GCD over NSOperation, but that doesn't mean such a case doesn't exist. I, however, agree with a general sentiment in terms of best-practice coding:
If you have a couple tools that suit the job (and in this case, you've got NSOperation vs a GCD block), use the class with the highest level of abstraction (ie, the highest level API). Not only is it typically easier to use/less code, you'll also gain from potential future enhancements introduced to the higher level APIs.
I'm doing this with Macruby, but I don't think that should matter much here.
I've got a model which stores its state in a dictionary data structure. I want concurrent operations to be updating this data structure sporadically. It seems to me like GCD offers a few possible solutions to this, including these two:
wrap any code that accesses the data structure in a block sent to some serial queue
use a GCD semaphore, with client code sending wait/signal calls as necessary when accessing the structure
When the queues in the first solution are synchronously called, then it seems pretty much equivalent to the semaphore solution. Do either of these solutions have clear advantages that I'm missing? Is there a better alternative I'm missing?
Also: would it be straightforward to implement a read-write (shared-exclusive) lock with GCD?
Serial Queue
Pros
there are not any lock
Cons
tasks can't work concurrently in the Serial Queue
GCD Semaphore
Pros
tasks can work concurrently
Cons
it uses lock even though it is light weight
Also we can use Atomic Operations instead of GCD Semaphore. It would be lighter than GCD Semaphore in some situation.
Synchronization Tools - Atomic Operations
Guarding access to the data structure with dispatch_sync on serial queue is semantically equivalent to using a dispatch semaphore, and in the uncontended case, they should both be very fast. If performance is important, benchmark and see if there's any significant difference.
As for the readers-writer lock, you can indeed construct one on top of GCD—at least, I cobbled something together the other day here that seems to work. (Warning: there be dragons/not-well-tested code.) My solution funnels the read/write requests through an intermediary serial queue before submitting to a global concurrent queue. The serial queue is suspended/resumed at the appropriate times to ensure that write requests execute serially.
I wanted something that would simulate a private concurrent dispatch queue that allowed for synchronisation points—something that's not exposed in the public GCD api, but is strongly hinted at for the future.
Adding a warning (which ends up being a con for dispatch queues) to the previous answers.
You need to be careful of how the dispatch queues are called as there are some hidden scenarios that were not immediately obvious to me until I ran into them.
I replaced NSLock and #synchronized on a number of critical sections with dispatch queues with the goal of having lightweight synchronization. Unfortunately, I ran into a situation that results in a deadlock and I have pieced it back to using the dispatch_barrier_async / dispatch_sync pattern. It would seem that dispatch_sync may opportunistically call its block on the main queue (if already executing there) even when you create a concurrent queue. This is a problem since dispatch_sync on the current dispatch queue causes a deadlock.
I guess I'll be moving backwards and using another locking technique in these areas.