在非OOP编程语言中,如C,如果我们只允许局部变量以各种可能的方式进行变异(更改内部字段,重新分配,......)但不允许变异函数参数,它会帮助吗我们阻止共享的可变状态?
注意,在这种情况下,函数main
可以启动10个线程(函数),并且这10个线程中的每一个都将接收对同一变量的不可变引用(在main
中定义)。但main
函数仍然可以更改该共享变量的值。那么这会导致并发/并行软件出现问题吗?
我希望问题很明确,但如果不是,请告诉我。
P.S。 “软件事务存储器(STM)”可以解决潜在的问题吗?就像Clojure提供的那样?
答案 0 :(得分:2)
是和否......这取决于平台,CPU,共享变量的大小和编译器。
在NVIDIA forum上,就GPU操作而言,类似的问题得到了非常巧妙的回答:
当多个线程在全局内存中写入或读取自然对齐位置时,所有线程读取或写入的数据类型相同,并且数据类型对应于单指令线程支持的类型之一访问...
(许多GPU单指令在事先知道时可处理16字节字(128位),但大多数CPU使用单指令32位或64位限制)
我撇开线程可能从CPU寄存器而不是实际内存中读取的机会(忽略对数据的更新),这些通常使用C中的volatile
关键字来解决。
但是,冲突和内存损坏仍然可能发生。
某些内存存储操作由内部(由CPU)或编译器(机器代码)使用大量存储调用处理。
在这些情况下,主要是在多核机器上(但不仅仅是),有“读者”和“#34;读者”的风险。将收到部分更新的信息,并且没有任何意义(即指针的一半是有效的而另一个是没有的。)
大于32位或64位的变量,通常会更新CPU" word" (不是OS字)一次(32位或64位)。
字节大小的变量是超级安全的,这就是为什么它们经常被用作标志......但它们应该可以使用操作系统或编译器提供的atomic_*
存储/写入操作来处理