确保我正确解释嵌套的GCD

时间:2016-01-16 13:45:38

标签: ios multithreading grand-central-dispatch

所以我使用 dispatch_async 将10个任务放在并发队列上。它们不会阻止下一个任务,并按顺序处理。我的用户界面很敏感。

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);

        });

    });
}

在每个任务中,我们模拟对数据库的写入,并且睡眠时间为#1;通过 dispatch_sync 串行队列上。

我一直认为dispatch_sync会阻止所有人,并同步其任务,因为这是我单独使用它时的行为方式。但是,在这种情况下,它不会阻止主线程。相反,它在背景中运行得很漂亮,就像我想要的那样。

是否因为与队列关联的线程受到影响?

例如,主线程通过dispatch_async执行并发队列,这就是为什么它不被阻止。

dispatch_sync仅对在并发队列上工作的后台线程进行同步和阻止。因此,dispatch_sync与后台线程相关联,因此永远不会影响我的UI主线程。

我的想法是否正确?

谢谢你!

2 个答案:

答案 0 :(得分:3)

您永远不会阻止主线程,因为您的代码在concurrencyQueue的线程或serialQueue的线程上运行。这些都不是主线。

sleep的所有调用都在serialQueue的主题上逐个发生。所以它是serialQueue被阻止的线程。

但是,由于您使用serialQueue调度到dispatch_sync,因此您还会阻止并发队列的每个线程。如果您在调用NSLog之后添加其他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);
    });
}

NSLog之后的第二个dispatch_sync会更好地向您展示dispatch_syncdispatch_async的调用的影响。

答案 1 :(得分:2)

是的,你是对的。 dispatch_sync()仅阻止运行队列的线程。