Deadlock with dispatch_sync

僤鯓⒐⒋嵵緔 提交于 2019-12-04 23:49:22

问题


{
    dispatch_queue_t myQueue = dispatch_queue_create("com.mycompany.myqueue", 0);

    dispatch_sync(myQueue, ^{

        //Do EXTREME PROCESSING!!!
        for (int i = 0; i< 100; i++) {
            [NSThread sleepForTimeInterval:.05];
            NSLog(@"%i", i);
        }

        dispatch_sync(dispatch_get_main_queue(), ^{
            [self updateLabelWhenBackgroundDone];
        });
    });
}

I am getting a deadlock here. According to Apple documentation

"dispatch_sync": "Submits a block to a dispatch queue for synchronous execution. Unlike dispatch_async, this function does not return until the block has finished. Calling this function and targeting the current queue results in deadlock.".

However, I do the outer dispatch_sync on myQueue and then I do inner ditpatch_sync on a different queue which is `main_queue.

Can not find out the reason for the deadlock. Any comments/help are appreciated here.


回答1:


If you dispatch_sync to myQueue like that and the call happens on the main thread, then dispatch_sync will, if possible, execute the block right there and not on a new worker thread like dispatch_async would. You're not guaranteed to get a separate worker thread for your queue.

The block then runs on the main thread until it hits your second dispatch_sync call, which happens to target the main queue. That queue can't be serviced, since there's already a block running on it, and that's where you end up in a deadlock.

If that's your problem, i.e. the first dispatch_sync is indeed coming from the main thread, then you should switch to dispatch_async. You wouldn't want to block the main thread with the long-running "EXTREME PROCESSING" operation.




回答2:


You are calling dispatch_sync twice. The first time suspends the main thread waiting for your block to complete. The block then suspends the background thread with the second call which tries to push back to the main thread (which will never process the block from its queue because it's suspended). Both threads are now waiting for each other.

At least one of the calls needs to be dispatch_async.




回答3:


I had similar problems and none of these solutions worked. I asked someone smarter than me.

My problem was I was spawning a dispatching an async worker block, and then displaying a progress window. Calls back into the main thread via

dispatch_sync(dispatch_get_main_queue(), ^{})

failed as did async calls.

The explanation was that the main thread was no longer in 'commons mode' because of the modal window. I replaced my calls to the main thread with this....

CFRunLoopPerformBlock(([[NSRunLoop mainRunLoop] getCFRunLoop]), (__bridge CFStringRef)NSModalPanelRunLoopMode, ^{
        //Update UI thread.

    });


来源:https://stackoverflow.com/questions/18297118/deadlock-with-dispatch-sync

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!