【发布时间】:2021-06-09 10:40:40
【问题描述】:
我编写了一个全局函数,允许我在 DispatchSemaphore 的帮助下同步等待异步任务的完成(仅用于实验目的!)。
///
/// synchronously waits for the completion of an asynchronous closure
/// - parameter handler: the task to run, asynchronously
/// - note: don't use this in production code, it violates
/// the Swift runtime contract of "forward" progress, it's never
/// safe to block a thread and wait for another thread to unblock it
/// (on a single core system, this may hang forever)
///
func sync(handler: @escaping () async -> Void) {
let sema = DispatchSemaphore(value: 0)
// default `Task.Priority` to `asyncDetached` is `nil`
Task.detached {
await handler()
sema.signal()
}
// blocks the current thread, waiting for the async Task to finish
sema.wait()
}
我注意到,如果我只使用 Task 块来启动异步任务,就会出现死锁,大概是因为 sema.wait() 阻塞了当前线程,从而阻止了 Task 块运行(正常 Task块似乎继承了当前线程),所以它会永远等待。
使用Task.detached 似乎不会阻塞线程,使上面的代码工作。
这似乎与分配了分离调用的Task.Priority? 有关。
调用Task.detached时,默认参数值为nil。
这可以自定义为不同的优先级,指示调度 QoS。
因此,我的问题是:Task.Priority? = nil 与什么线程相关?它似乎与它从哪里启动的线程不同。 Task.Priority? = nil 是否指示 Swift 运行时始终在不同的线程上运行?
编辑
继续提问 - Task 和 Task.detached 在线程方面有何不同?
【问题讨论】:
标签: swift multithreading asynchronous async-await