Making sure I'm explaining nested GCD correctly

拟墨画扇 提交于 2019-12-13 02:13:48

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!