我尝试了多个关于stackoverflow的解决方案/答案,但是没有一个对我有用。其中一些如下:
https://stackoverflow.com/a/30495424/3145189
Is this safe to call wait() of DispatchSemaphore several times at one time?
https://stackoverflow.com/a/37155631/3145189
我正在尝试实现一个非常简单的功能,无论从哪个线程调用它,代码块或函数都应按顺序执行。
我的示例代码:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
DispatchQueue.global().async {
self.testLog(name:"first")
}
DispatchQueue.global().async {
self.testLog(name:"second")
}
DispatchQueue.main.async {
self.testLog(name: "mainthread")
}
}
func testLog(name:String) -> Void {
for i in 1..<1000 {
print("thread test \(i) name =\(name)")
}
}
所以输出应该像-
第一次线程调用
线程测试1名称= first
线程测试2名称= first
线程测试3名称= first
。
。
。
线程测试999 name = first
第二个线程调用
线程测试1名称=秒
线程测试2名称= second
。
。
。
线程测试999 name = second
主线程调用
线程测试1名称= mainthread
线程测试2名称= mainthread
。
。
。
线程测试999名称= mainthread
如果在第一个线程上调用了该函数,则该功能应仅继续对第一个线程进行打印日志。线程的顺序可能会有所不同,我不在乎,即使先打印主线程日志,然后再打印第二和第一个无关紧要的日志也应该进行分组。
答案 0 :(得分:3)
这将顺序执行调用。
保留对serialQueue
的引用,您可以从任何线程提交块。
let serialQueue = DispatchQueue(label: "serial_queue")
serialQueue.async {
self.testLog(name: "first")
}
serialQueue.async {
self.testLog(name: "second")
}
serialQueue.async {
self.testLog(name: "third")
}
答案 1 :(得分:0)
我正在尝试实现一个非常简单的功能,无论从哪个线程调用它,代码块或函数都应按顺序执行。
要串行执行,请使用Dispatch串行队列。如果您正在编写类或结构,则可以在类/结构级别使用static let
来存储您的序列化函数可以分派到的队列。在这种情况下,static let
相当于某些语言中的“类变量”。
如果您使用(Objective-)C编写此类变量,那么也可以在函数级别声明该变量,即具有全局生存期但范围限于函数内的变量。 Swift在函数中不支持这些,但是您可以将结构的作用域限定为函数...
func testLog(name:String) -> Void
{
struct LocalStatics
{
static let privateQueue = DispatchQueue(label: "testLogQueue")
}
// run the function body on the serial queue - could use async here
// and the body would still run not interleaved with other calls but
// the caller need not wait for it to do so
LocalStatics.privateQueue.sync {
for i in 1..<1000
{
print("thread test \(i) name =\(name)")
}
}
}
(有关Swift中“局部静态”的讨论,请参见this SO Q&A)