Objective-C multithreaded devices: GCD against locks

I am discussing whether to move on to a GCD-based template for multi-threaded accessories. I have been using lock-based user synchronization in accessors for many years, but I found some information ( Introduction to GCD ), and there seem to be advantages to the GCD oriented approach. I hope to start a dialogue here to help myself, while others are weighing the decision.

The sample looks like this:

- (id)something { __block id localSomething; dispatch_sync(queue, ^{ localSomething = [something retain]; }); return [localSomething autorelease]; } - (void)setSomething:(id)newSomething { dispatch_async(queue, ^{ if(newSomething != something) { [something release]; something = [newSomething retain]; [self updateSomethingCaches]; } }); } 

On the pro side: you get the advantage of possibly non-blocking write access; Lower overhead than blocking (maybe?); safety from forgetting to unlocking before returning from critical sections of code; others?

Cons: Exception handling does not exist, so you need to code it in every block that you might need.

Is this a potentially recommended method for writing multi-threaded accessories?

Are there standard approaches for creating dispatch queues for this purpose? In other words, best practices for trading from granularity? For example, using locks, the lock for each attribute is more subtle than the lock on the entire object. With dispatch queues, I could imagine that creating one queue for all objects would create performance bottlenecks, so are object queues suitable? Obviously, the answer is highly application-specific, but there are known trade-offs with performance to help evaluate the feasibility of the approach.

Any information / understanding will be appreciated.

+7
source share
1 answer

Is this pattern a potentially recommended method for writing multi-threaded accessors?

I think you wrote it with a sequential queue, but there is no reason for this. Consider this:

 dispatch_queue_t queue = dispatch_queue_create("com.example", DISPATCH_QUEUE_CONCURRENT); // same thing as your example - (NSString*)something { __block NSString *localSomething; dispatch_sync(queue, ^{ localSomething = _something; }); return localSomething; } - (void)setSomething:(NSString*)something { dispatch_barrier_async(queue, ^{ _something = something; }); } 

It reads at the same time, but uses a send barrier to disable concurrency while writing. A big advantage of GCD is that it allows simultaneous reading instead of locking the entire object, like @property (atomic).

Both asynchronous (dispatch_async, dispatch_barrier_async) are faster from the client point of view, but slower than synchronization, because they must copy a block and have a block of such a small task, the time it takes to copy becomes meaningful. I’m more likely to return to the client, so everything is fine with him.

+8
source

All Articles