GCD 串行异步队列与嵌套在异步中的串行同步队列
GCD serial async queue vs serial sync queue nested in async
我必须保护代码的关键部分。
我不希望调用者被可能耗时的函数阻塞,所以我创建了一个带有后台 qos 的串行队列,然后异步调度:
private let someQueue = DispatchQueue(label: "\(type(of: self)).someQueue", qos: .background)
func doSomething() {
self.someQueue.async {
//critical section
}
}
根据我的理解,该函数将直接 return 在调用线程上而不阻塞。
我还看到某个地方首先在全局队列上异步调度,然后在串行队列上同步调度:
private let someQueue2 = DispatchQueue(label: "\(type(of: self)).someQueue2")
func doSomething() {
DispatchQueue.global(qos: .background).async {
self.someQueue2.sync {
//critical section
}
}
}
这两种方法有什么区别?
哪种方法正确?
在第一种方法中,调用线程不会被阻塞,异步块中传递的任务(临界区)将在后台执行。
在第二种方法中,调用线程未被阻塞,但“后台”线程将等待另一个线程执行的同步块(临界区)执行。
我不知道你在关键部分做了什么,但似乎第一种方法似乎是最好的方法。请注意,后台 qos 非常慢,可以为您的队列使用默认 qos,除非您知道自己在做什么。另请注意,约定要求您使用包标识符作为队列的标签。所以像这样:
private let someQueue = DispatchQueue(label: "\(Bundle.main.bundleIdentifier ?? "").\(type(of: self)).someQueue")
我必须保护代码的关键部分。 我不希望调用者被可能耗时的函数阻塞,所以我创建了一个带有后台 qos 的串行队列,然后异步调度:
private let someQueue = DispatchQueue(label: "\(type(of: self)).someQueue", qos: .background)
func doSomething() {
self.someQueue.async {
//critical section
}
}
根据我的理解,该函数将直接 return 在调用线程上而不阻塞。 我还看到某个地方首先在全局队列上异步调度,然后在串行队列上同步调度:
private let someQueue2 = DispatchQueue(label: "\(type(of: self)).someQueue2")
func doSomething() {
DispatchQueue.global(qos: .background).async {
self.someQueue2.sync {
//critical section
}
}
}
这两种方法有什么区别? 哪种方法正确?
在第一种方法中,调用线程不会被阻塞,异步块中传递的任务(临界区)将在后台执行。
在第二种方法中,调用线程未被阻塞,但“后台”线程将等待另一个线程执行的同步块(临界区)执行。
我不知道你在关键部分做了什么,但似乎第一种方法似乎是最好的方法。请注意,后台 qos 非常慢,可以为您的队列使用默认 qos,除非您知道自己在做什么。另请注意,约定要求您使用包标识符作为队列的标签。所以像这样:
private let someQueue = DispatchQueue(label: "\(Bundle.main.bundleIdentifier ?? "").\(type(of: self)).someQueue")