闭包线程安全吗?



假设我有一个这样的类:

class Bla {
var callback: (() -> Void)?
// doStuff will be called from multiple threads
func doStuff() {
callback?()
}
}
从多个线程调用闭包是线程安全的吗?在此期间不能修改闭包,只能调用。

闭包内部是线程安全代码。

不幸的是,线程安全不是一个直截了当的问题。具体来说,虽然对块的读取对多个线程来说是安全的。

在swift闭包中是通过引用传递的。当你把它赋值给var callback时它在堆中接收一个内存地址。该地址可以被多个线程同时读取,只要变量在其他线程读取访问时没有改变。即使在块中捕获了一个变量,该变量也会被块捕获,如果它不是引用类型,甚至可以被闭包修改。不过,在调用站点内的操作一定要小心。例如,如果闭包是由多个线程调用的,而你在里面传递了…

var i = 0 
callback = {
i += 1
}

for _ in 0...100 {

DispatchQueue.global().async {
bla.closure()
}
}

这显然不再被认为是"线程安全"的;因为你仍然在通过多个线程进行变异。例如,两个或三个线程可能读取1并添加1,另外十二个线程可能读取5并在返回时写入6;或者更糟糕的是,第二个线程最后完成,在100次调用之后,您得到I = 2。

另外,if "var i"如果是引用类型,程序可能会在错误访问异常时崩溃。

最新更新