菜鸟教程小白 发表于 2022-12-12 10:40:50

ios - 单线程调用两次performBlockAndWait是否会导致死锁?


                                            <p><p>我在<code>performBlockAndWait</code> 文档中发现了类似这样的内容:</p>

<blockquote>
<p>This method may safely be called reentrantly.</p>
</blockquote>

<p>我的问题是这是否意味着它永远不会导致死锁,例如会像在单个上下文中那样调用它吗?:</p>

<pre><code>NSManageObjectContext *context = ...

[context performBlockAndWait:^{
       // ... some stuff

       [context performBlockAndWait:^{

       }];
}];
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您可以使用一小段代码自行尝试 ;) </p>

<p>但确实,它不会死锁。 </p>

<p>我怀疑,内部实现使用队列特定 token 来识别代码执行的当前队列(参见 <code>dispatch_queue_set_specific</code> 和 <code>dispatch_queue_get_specific</code>)。</p >

<p>如果它确定当前正在执行的代码在它自己的私有(private)队列或子队列上执行,它会简单地绕过同步提交 block ——这会导致死锁,而是直接执行它。</p>

<p>一个可能的实现如下所示:</p>

<pre><code>func executeSyncSafe(f: () -&gt; ()) {
    if isSynchronized() {
      f()
    } else {
      dispatch_sync(syncQueue, f)
    }
}

func isSynchronized() -&gt; Bool {
    let context = UnsafeMutablePointer&lt;Void&gt;(Unmanaged&lt;dispatch_queue_t&gt;.passUnretained(syncQueue).toOpaque())
    return dispatch_get_specific(&amp;queueIDKey) == context
}
</code></pre>

<p>队列可以这样创建:</p>

<pre><code>private var queueIDKey = 0// global


init() {
    dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL,
            QOS_CLASS_USER_INTERACTIVE, 0))
    let context = UnsafeMutablePointer&lt;Void&gt;(Unmanaged&lt;dispatch_queue_t&gt;.passUnretained(syncQueue).toOpaque())
    dispatch_queue_set_specific(syncQueue, &amp;queueIDKey, context, nil)
}
</code></pre>

<p><code>dispatch_queue_set_specific</code> 将一个<em>token</em>(这里是<code>context</code> - 它只是队列的指针值)与某个<em>key</em> 该队列。稍后,您可以尝试为指定 <em>key</em> 的任何队列检索该 token ,并检查当前队列是同一队列还是子队列。如果是这样,则绕过对队列的调度,而是直接调用函数 <code>f</code>。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 单线程调用两次performBlockAndWait是否会导致死锁?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/35577556/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/35577556/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 单线程调用两次performBlockAndWait是否会导致死锁?