main 中创建的同步调用串行队列正常,而 main 中的同步调用主队列为 DEAD-LOCK

Posted

技术标签:

【中文标题】main 中创建的同步调用串行队列正常,而 main 中的同步调用主队列为 DEAD-LOCK【英文标题】:Sync call serial queue created in main is OK while sync call main queue in main is DEAD-LOCK 【发布时间】:2016-12-24 09:26:50 【问题描述】:
int main(void) 
    dispatch_queue_t queue = dispatch_queue_create(“com.somecompany.queue”, nil);
    dispatch_sync(queue, ^ // task 1
        NSLog(@"Situation 1"); 
    );
    return 0;

这没关系在main()中运行。

//-----------------------------------------------------------

int main(void) 
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^ // task 1
        NSLog(@"Situation 2"); 
    );
    return 0;

这是 main() 中的死锁。

//-----------------------------------------------------------

为什么情况 1 是 OK 而情况 2 是 DEAD-LOCK ?两者都是主线程中的同步调用串行队列。

或者仅仅因为 sync() 本身在主队列中运行?

【问题讨论】:

【参考方案1】:

在第一种情况下,您阻塞主队列,直到任务在您创建的调度队列上执行完毕,所以没有问题。

在第二种情况下,您尝试在主队列上调度任务,但主队列被dispatch_sync 阻塞,因此提交的闭包无法启动。结果是死锁

【讨论】:

也就是说,int main(void) NSLog(@"Task 1"); return 0;NSLog() 在主队列上运行?还是main()中运行的所有函数都运行在主队列上? 程序中的所有内容都在主队列上运行,但您明确分派到另一个队列的代码除外。主队列上的代码将始终在主线程上运行。在另一个队列上调度的代码可能会也可能不会在主线程上运行。 哦原来如此!谢谢@Paulw11,现在我知道了。

以上是关于main 中创建的同步调用串行队列正常,而 main 中的同步调用主队列为 DEAD-LOCK的主要内容,如果未能解决你的问题,请参考以下文章

如何同步 URLSession 任务的串行队列?

为啥从并发队列异步调用`DispatchQueue.main.sync`成功但同步失败?

多线程处理怎么使用绿联

您如何将 main 中创建的实例传递给类?

ios多线程同步异步、串行并行队列、死锁

照片框架中创建的相册中图像的 iCloud 同步