C语言 一个全局变量被三个线程(2个writers,1个reader)访问,而没有任何同步可能是未定义的吗?

nafvub8i  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(76)

在windows/Linux多线程C程序中,如果unsigned int全局变量被三个线程访问而没有任何同步,其中

  • 线程1写入值0
  • 线程2写入值0xFFFFFFFF
  • 线程3读取值
    问题

线程3是否可以从全局变量中获取部分值,比如0x 0000 FFFF?
我一直认为,如果unsigned int正确对齐,则写操作是原子的,因此在本例中,线程3将始终为0或0xFFFFFFFF。

xytpbqjk

xytpbqjk1#

你忘了一个很有可能的案例:线程3根本不读取值,而是使用先前读取的值。
同步不仅仅是防止部分读/写;它还通知CPU和编译器该值可能被另一个线程更改。他们可以假设如果没有同步,就不会发生这种情况,因此可以使用缓存值,或者可以优化读取,等等。
(我在这里使用的术语“同步”是松散的。)
考虑到这种可能性,你是否能最终得到0000 FFFF是没有意义的。

piv4azn7

piv4azn72#

线程3是否可以从全局变量中获取部分值,比如0x0000FFFF?
你的程序包含了一个数据竞争,因此它的行为对于C来说是未定义的。原则上,是的,线程3可以观察到一个不同于变量初始值的值,也可以观察到一个不同于线程1和线程2写入的值的值,没有限制。
我一直认为,如果unsigned int正确对齐,则写操作是原子的,因此在本例中,线程3将始终为0或0xFFFFFFFF。
试图根据自己的源代码如何对应于较低级别指令的模型来预测C程序的行为是错误的。如果您编写的代码的行为由C语言规范很好地定义,则不需要尝试这样做。
尽管如此,在你描述的情况下,你的特定C实现可能永远不会表现出你所要求的那种剪切,但即使如此,这也不会使你的racy代码安全。它的行为仍然是未定义的,在实践中它仍然可能表现出错误的行为。例如线程3从不观察其他两个线程的写入。

相关问题