OS X上的GCD死锁,但iOS上没有

时间:2015-07-20 23:30:16

标签: ios objective-c multithreading grand-central-dispatch

我在viewDidLoad

中有这段代码
- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    NSLog(@"First");
    dispatch_async(queue, ^{
        NSLog(@"Third");
        dispatch_sync(queue, ^{
            NSLog(@"Fourth");
        });
        NSLog(@"Last");
    });
    NSLog(@"Second");
}

打印出来:

2015-07-20 19:12:54.325 Test[7574:431705] First
2015-07-20 19:12:54.326 Test[7574:431736] Third
2015-07-20 19:12:54.326 Test[7574:431736] Fourth
2015-07-20 19:12:54.326 Test[7574:431705] Second
2015-07-20 19:12:54.326 Test[7574:431736] Last

这在某些执行方面也有所不同。有时会打印“First,Second,Third,Fourth,Last”,有时会生成上面的输出。

另外,我有一个test.m文件,其中包含以下内容:     #include

int main() {
  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
  NSLog(@"First");
  dispatch_async(queue, ^{
      NSLog(@"Third");
      dispatch_sync(queue, ^{
          NSLog(@"Fourth");
        });
      NSLog(@"Last");
    });
  NSLog(@"Second");
  return 0;
}

这会产生:

2015-07-20 19:12:36.067 tester[7568:431388] First
2015-07-20 19:12:36.068 tester[7568:431388] Second

我不明白为什么在iOS模拟器上打印出所有日志,而在Mac上它打印“First”和“Second”然后死锁。我预计iOS代码也会死锁,但它打印出“第三”和“第四”。没有任何其他处理iOS代码中的线程。此外,当NSLog(@"First")被注释掉时,在test.m的某些执行中,它会产生不同的内容,如下所示:

$: ./tester
2015-07-20 19:19:31.030 tester[7608:433729] Second
$: ./tester
2015-07-20 19:19:32.268 tester[7609:433738] Third
2015-07-20 19:19:32.268 tester[7609:433737] Second
$ ./tester
2015-07-20 19:19:32.620 tester[7610:433740] Second
$: ./tester
2015-07-20 19:19:33.812 tester[7611:433744] Third
2015-07-20 19:19:33.812 tester[7611:433743] Second

我不知道造成输出差异的原因。这是iOS处理与OS X不同的线程的方式吗?如果有人能解释发生了什么,我将不胜感激

1 个答案:

答案 0 :(得分:2)

在Mac上你没有死锁。这是main完成的简单情况,应用程序在后台线程有机会开始或完成之前终止。

请记住,在日志中看到“Second”和“Third”的顺序是未定义的。到dispatch_async返回时,您现在有两个并发线程,因此主队列上的NSLog和后台队列可以按任意顺序输出。

如果在sleep语句之前阻塞主线程(例如使用return),则应该看到来自两个线程的所有日志。