如果我们只允许局部变量是可变的,我们可以防止共享可变状态吗?
Can we prevent shared mutable state if we only allow local variables to be mutable?
在非 OOP 编程语言中,如 C,如果我们只允许以各种可能的方式改变局部变量(更改内部字段、重新分配、...)但不允许函数参数的改变,将会它帮助我们防止共享可变状态?
请注意,在这种情况下,函数 main
可以启动 10 个线程(函数),这 10 个线程中的每一个都将收到对同一变量(在 main
中定义)的不可变引用。但是 main
函数仍然可以更改该共享变量的值。那么这会导致 concurrent/parallel 软件出现问题吗?
我希望问题很清楚,如果不清楚请告诉我。
P.S。 "software transactional memory (STM)" 能否解决潜在问题?喜欢 Clojure 提供的功能吗?
是和否...这取决于平台、CPU、共享变量的大小和编译器。
在一个NVIDIA forum上,关于GPU操作,一个类似的问题得到了非常巧妙的回答:
When multiple threads are writing or reading to/from a naturally aligned location in global memory, and the datatype being read or written is the same by all threads, and the datatype corresponds to one of the supported types for single-instruction thread access ...
(许多GPU单指令在事先知道的情况下可以处理16字节字(128位),但大多数CPU使用单指令32位或64位限制)
我忽略了线程可能从 CPU 寄存器而不是实际内存中读取的机会(忽略对数据的更新),这些大多可以使用 volatile
关键字解决C.
但是,冲突和内存损坏仍然会发生。
一些内存存储操作在内部处理(由 CPU)或由您的编译器(机器代码)使用大量存储调用处理。
在这些情况下,主要是在多核机器上(但不仅如此),存在风险 "reader" 将收到部分更新且没有任何意义的信息(即指针的一半一个有效,另一个无效)。
大于 32 位或 64 位的变量,通常 会更新为 CPU "word"(不是 OS 字)时间(32 位或 64 位)。
字节大小的变量是超级安全的,这就是为什么它们经常被用作标志...但它们可能应该使用 [=41= 提供的 atomic_*
store/write 操作来处理] 或编译器。
在非 OOP 编程语言中,如 C,如果我们只允许以各种可能的方式改变局部变量(更改内部字段、重新分配、...)但不允许函数参数的改变,将会它帮助我们防止共享可变状态?
请注意,在这种情况下,函数 main
可以启动 10 个线程(函数),这 10 个线程中的每一个都将收到对同一变量(在 main
中定义)的不可变引用。但是 main
函数仍然可以更改该共享变量的值。那么这会导致 concurrent/parallel 软件出现问题吗?
我希望问题很清楚,如果不清楚请告诉我。
P.S。 "software transactional memory (STM)" 能否解决潜在问题?喜欢 Clojure 提供的功能吗?
是和否...这取决于平台、CPU、共享变量的大小和编译器。
在一个NVIDIA forum上,关于GPU操作,一个类似的问题得到了非常巧妙的回答:
When multiple threads are writing or reading to/from a naturally aligned location in global memory, and the datatype being read or written is the same by all threads, and the datatype corresponds to one of the supported types for single-instruction thread access ...
(许多GPU单指令在事先知道的情况下可以处理16字节字(128位),但大多数CPU使用单指令32位或64位限制)
我忽略了线程可能从 CPU 寄存器而不是实际内存中读取的机会(忽略对数据的更新),这些大多可以使用 volatile
关键字解决C.
但是,冲突和内存损坏仍然会发生。
一些内存存储操作在内部处理(由 CPU)或由您的编译器(机器代码)使用大量存储调用处理。
在这些情况下,主要是在多核机器上(但不仅如此),存在风险 "reader" 将收到部分更新且没有任何意义的信息(即指针的一半一个有效,另一个无效)。
大于 32 位或 64 位的变量,通常 会更新为 CPU "word"(不是 OS 字)时间(32 位或 64 位)。
字节大小的变量是超级安全的,这就是为什么它们经常被用作标志...但它们可能应该使用 [=41= 提供的 atomic_*
store/write 操作来处理] 或编译器。