问题
So I'm putting 10 tasks on a concurrent queue using dispatch_async. They do not block the next task, and gets processed in order. My UI is responsive.
for (int i = 0; i < 10; i++) {
dispatch_async(concurrencyQueue, ^() {
NSLog(@"..calling insertion method to insert record %d", i);
dispatch_sync(serialQueue, ^() {
//this is to simulate writing to database
NSLog(@"----------START %d---------", i);
[NSThread sleepForTimeInterval:1.0f];
NSLog(@"--------FINISHED %d--------", i);
});
});
}
Within each task, we simulate a write to database with a "1 sec sleep" on a serial Queue via dispatch_sync.
I always thought dispatch_sync blocks everyone, and syncs its tasks because that's how it behaves when I use it individually. However, in this situation, it does not block the main thread. Instead, it runs beautifully in the background like I want it.
Is it because whatever thread is associated with the queue is being affected?
For example, the main thread is executing the concurrent queue via dispatch_async and that's why it is not blocked.
The dispatch_sync only syncs and blocks against the background thread that's working on the concurrent queue. Hence, the dispatch_sync is associated with the background thread, thus never affecting my UI main thread.
Is my thinking correct?
thank you!
回答1:
You never block the main thread because your code is running on either the threads of the concurrencyQueue
or the thread of the serialQueue
. None of those are the main thread.
All of the calls to sleep
happen one by one on the thread of the serialQueue
. So it is the thread of the serialQueue
that is blocked.
However, since you dispatch to the serialQueue
using dispatch_sync
, you are also blocking each thread of the concurrent queue. This would be better pictured if you add another NSLog
after the call to dispatch_sync
.
for (int i = 0; i < 10; i++) {
dispatch_async(concurrencyQueue, ^() {
NSLog(@"..calling insertion method to insert record %d", i);
dispatch_sync(serialQueue, ^() {
//this is to simulate writing to database
NSLog(@"----------START %d---------", i);
[NSThread sleepForTimeInterval:1.0f];
NSLog(@"--------FINISHED %d--------", i);
});
NSLog(@"..called insertion method to insert record %d", i);
});
}
That 2nd NSLog
after the dispatch_sync
will show you better how the dispatch_sync
is affecting the calls to dispatch_async
.
回答2:
Yes, you are right. dispatch_sync()
blocks only the thread the queue is running on.
来源:https://stackoverflow.com/questions/34827677/making-sure-im-explaining-nested-gcd-correctly