你們的知道在主隊列上使用dispatch_sync(),async
- (void)testSyncMainThread { dispatch_queue_t main = dispatch_get_main_queue(); NSLog(@"*********1"); dispatch_sync(main, ^(){ NSLog(@"*********2"); }); NSLog(@"*********3"); }
會形成線程阻塞,可是查找網上說的緣由,發現基本上說法都是同樣的,感受不是不太好理解,函數
我查看一下API, this
/*!spa
* @function dispatch_sync線程
*code
* @abstractorm
* Submits a block for synchronous execution on a dispatch queue.blog
*隊列
* @discussionget
* 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"); });
效果是同樣的