使用“sync”分派到队列和使用带有“.wait”标志的工作项之间的区别?

Posted

技术标签:

【中文标题】使用“sync”分派到队列和使用带有“.wait”标志的工作项之间的区别?【英文标题】:Difference between dispatching to a queue with `sync` and using a work item with a `.wait` flag? 【发布时间】:2016-06-29 16:17:46 【问题描述】:

我正在学习苹果的 GCD,正在观看视频Concurrent Programming With GCD in Swift 3。

在本视频的 16:00,DispatchWorkItem 的标志被描述为 .wait,其功能和图表都显示了我认为 myQueue.sync(execute:) 的用途。

所以,我的问题是;有什么区别:

myQueue.sync  sleep(1); print("sync") 

还有:

myQueue.async(flags: .wait)  sleep(1); print("wait") 
// NOTE: This syntax doesn't compile, I'm not sure where the `.wait` flag moved to.
// `.wait` Seems not to be in the DispatchWorkItemFlags enum.

似乎这两种方法在等待命名队列时都会阻塞当前线程:

    完成任何当前或之前的工作(如果连续) 完成给定的块/工作项

我对此的理解一定有问题,我错过了什么?

【问题讨论】:

【参考方案1】:

.wait 不是 DispatchWorkItemFlags 中的标志,这就是为什么 你的代码

myQueue.async(flags: .wait)  sleep(1); print("wait") 

不编译。

wait() is a method of DispatchWorkItem 只是一个包装器 dispatch_block_wait().

/*!
 * @function dispatch_block_wait
 *
 * @abstract
 * Wait synchronously until execution of the specified dispatch block object has
 * completed or until the specified timeout has elapsed.

简单示例:

let myQueue = DispatchQueue(label: "my.queue", attributes: .concurrent)
let workItem = DispatchWorkItem 
    sleep(1)
    print("done")

myQueue.async(execute: workItem)
print("before waiting")
workItem.wait()
print("after waiting")

dispatchMain()

【讨论】:

谢谢。似乎它为您提供了比sync 更多的控制粒度。 dispatchMain() 在做什么? @SimplGy:developer.apple.com/reference/dispatch/1452860-dispatch_main。你需要在没有运行循环的程序中(例如命令行程序)来保持 GCD 运行。在 Playground 中,您可以使用 PlaygroundPage.current.needsIndefiniteExecution = true (***.com/questions/24058336/…) 实现相同的效果(我认为) @MartinR 谢谢!一个小问题:如果workItem 块内的代码是异步的怎么办?例如SKTextureAtlaspreload(completionHandler:)。我们如何确保workItem 将等待该代码完成,然后才将自己标记为已完成? @damirstuhec:DispatchGroup 可能是您正在寻找的。​​span> @MartinR 不确定DispatchGroup 是否是我需要的。 DispatchGroup 不是用于将DispatchQueue 分组以在他们完成队列中的任务时得到通知吗?我只是在寻找一种在 DispatchWorkItem 内执行异步代码块的方法,它应该等待它完成。

以上是关于使用“sync”分派到队列和使用带有“.wait”标志的工作项之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章

Python中的sync和wait函数的使用

Combine 的 receive(on:) 没有分派到串行队列,导致数据竞争

如何将链式作业分派到 Lumen 6 中的队列?

Swift - 分派到主队列是不是足以使 var 线程安全?

Java wait和notifyAll的使用,简单的阻塞队列实现

sync.WaitGroup和sync.Once