crystal-lang 中来自多个线程的静态变量的突变是否安全?
Is mutation safe on a static variable from multiple thread in crystal-lang?
考虑这个例子 -
class Test
@@store = ""
end
这里的 store 是 Test
的 class 变量,可以从任何地方改变。
假设我在多线程模式下运行我的程序,因此可以一次从多个线程更改变量存储。
我的问题是 - 是否会出现死锁或 crystal-lang 由于光纤调度以某种方式处理它?
如果出现死锁,推荐的解决上述程序的方法是什么。如果你能提供这个问题的代码,那会更好。
不,不会出现死锁,因为 Crystal 不对变量访问进行隐式锁定。但是像这样编写具有全局状态的线程不安全代码非常容易。
不好的例子:
module Test
@@store = "a"
def self.run
spawn do
@@store = @@store == "a" ? "b" : "c"
end
@@store = @@store == "b" ? "d" : "e"
end
end
Test.run
当 运行 这个多线程程序 @@store
可能是 "b"
、"c"
、"d"
或 "e"
结束时程序(实际上你很少会看到除了一个结果之外的所有结果,因为没有太多的事情发生,也没有太多的争用,所以它在执行环境中会非常稳定)。
Crystal 提供了一些同步原语,例如 Mutex
和 Atomic
,但一般建议更喜欢通过 Channel
传递不可变数据而不是可变数据共享纤维之间。
考虑这个例子 -
class Test
@@store = ""
end
这里的 store 是 Test
的 class 变量,可以从任何地方改变。
假设我在多线程模式下运行我的程序,因此可以一次从多个线程更改变量存储。
我的问题是 - 是否会出现死锁或 crystal-lang 由于光纤调度以某种方式处理它?
如果出现死锁,推荐的解决上述程序的方法是什么。如果你能提供这个问题的代码,那会更好。
不,不会出现死锁,因为 Crystal 不对变量访问进行隐式锁定。但是像这样编写具有全局状态的线程不安全代码非常容易。
不好的例子:
module Test
@@store = "a"
def self.run
spawn do
@@store = @@store == "a" ? "b" : "c"
end
@@store = @@store == "b" ? "d" : "e"
end
end
Test.run
当 运行 这个多线程程序 @@store
可能是 "b"
、"c"
、"d"
或 "e"
结束时程序(实际上你很少会看到除了一个结果之外的所有结果,因为没有太多的事情发生,也没有太多的争用,所以它在执行环境中会非常稳定)。
Crystal 提供了一些同步原语,例如 Mutex
和 Atomic
,但一般建议更喜欢通过 Channel
传递不可变数据而不是可变数据共享纤维之间。