iOS Dispatch_sync 阻塞线程的原因

本文探讨了在主队列上使用dispatch_sync()造成线程阻塞的问题。通过查看API,分析出代码执行到dispatch_sync()时,先将其放入主队列且等待block任务完成才返回,再把block任务放入主队列,因同步执行且相互依赖造成死锁,还在其他队列模拟出相同死锁情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家的知道在主队列上使用dispatch_sync(),

- (void)testSyncMainThread {
    
    dispatch_queue_t main = dispatch_get_main_queue();
    NSLog(@"*********1");
    dispatch_sync(main, ^(){
            NSLog(@"*********2");
    });
    NSLog(@"*********3");
}

 

会造成线程阻塞,但是查找网上说的原因,发现基本上说法都是一样的,感觉不是不太好理解,

我查看一下API, 

/*!

 * @function dispatch_sync

 *

 * @abstract

 * Submits a block for synchronous execution on a dispatch queue.

 *

 * @discussion

 * Submits a workitem to a dispatch queue like dispatch_async(), however

 * dispatch_sync() will not return until the workitem has finished.

 *

 * Work items submitted to a queue with dispatch_sync() do not observe certain

 * queue attributes of that queue when invoked (such as autorelease frequency

 * and QOS class).

 *

 * Calls to dispatch_sync() targeting the current queue will result

 * in dead-lock. Use of dispatch_sync() is also subject to the same

 * multi-party dead-lock problems that may result from the use of a mutex.

 * Use of dispatch_async() is preferred.

 *

 * Unlike dispatch_async(), no retain is performed on the target queue. Because

 * calls to this function are synchronous, the dispatch_sync() "borrows" the

 * reference of the caller.

 *

 * As an optimization, dispatch_sync() invokes the workitem on the thread which

 * submitted the workitem, except when the passed queue is the main queue or

 * a queue targetting it (See dispatch_queue_main_t,

 * dispatch_set_target_queue()).

 *

 * @param queue

 * The target dispatch queue to which the block is submitted.

 * The result of passing NULL in this parameter is undefined.

 *

 * @param block

 * The block to be invoked on the target dispatch queue.

 * The result of passing NULL in this parameter is undefined.

 */

 

结合API,我的理解:

第一步:当代码执行到 dispatch_sync()时,会首先把dispatch_sync()函数放到当前线程的队列(就是主队列中),而且这个线程并不会立即返回,而是会等待block中的任务都完成时才会返回,

第二步:再把block中的任务依次放到主队列中等待执行,

 

由于是同步执行,而且block中的任务在主队列的线性表中的前面有个dispatch_sync()等待完成,而dispatch_sync()的完成又依赖于block的执行完成,就这样造成了死锁。

 

最后:在其他队列上模拟这种死锁情况

 dispatch_queue_t lwMainQueue = dispatch_queue_create("lw.queue", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(lwMainQueue, ^{
        NSLog(@"*********1");
        dispatch_sync(lwMainQueue, ^{NSLog(@"*********2");
        });
    NSLog(@"*********3");
    });

效果是一样的

 

转载于:https://www.cnblogs.com/liuwenqiang/p/10943840.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值