繁体   English   中英

C ++是从不同的线程编写和读取变量的未定义行为

[英]C++ Is writing and reading a variable from different threads undefined behavior

自从我开始多线程以来,我一直在问自己这个问题:

是从不同的线程编写和读取变量未定义的行为?

让我们使用最小的例子,我们在一个线程中递增一个整数并读取另一个中的整数。

void thread1()
{
    x++;
}

void thread2()
{
    if (x == 5)
    {
        //doSomething
    }
}

我理解添加操作不是原子的,因此我可以在第一个线程处于添加操作的中间时从第二个线程读取,但是有些东西我不太确定。

x是否保持其值直到整个加法操作完成然后被赋予此新值,或者x是否具有中间状态,其中从中读取将导致未定义的行为。

如果第一个理论适用,那么在写入时从x读取只会在添加之前返回值,并且不会出现问题。

如果第二个理论是正确的,那么有人可以更详细地解释添加操作的过程是什么以及为什么它将是未定义的行为(可能有一个例子?)

谢谢

评论已经得到了正确的基础知识。

编译单个函数时,编译器可以考虑变量的更改方式。 如果函数不能直接或间接地改变某个变量,那么编译器可以假设该变量没有任何变化, 除非有线程同步。 在这种情况下,编译器必须处理另一个线程更改这些变量的可能性。

如果违反了编译器假设(即你有一个bug),那么任何事情都可能发生。 这不受限制,因为这会严重限制优化器。 你可以假设x在内存中有一些唯一的地址,但是已知优化器可以移动变量并让多个变量共享一个地址(只是在不同的时间)。 基于单线程假设,这种优化很可能是合理的,这是您的示例违反的假设。 你的第二个线程可能会认为它正在看x ,但也可能会得到y

x(32位变量)将始终在32 +位cpu上定义,但不是那么精确。 您知道x可以是++定义的从开始到结束范围的任何值。

类似于下面的情况:x被初始化为0并且你调用5次thread1,线程2可以看到这个x在0到5的范围内。

这意味着我可以考虑将整数分配给内存作为原子。

有两个原因导致两个线程上的x不同步,例如,当thread1上的x为5时,thread2上的x可以同时为0。 其中一个原因是cpu cache对于每个核心都是不同的。 要同步缓存之间的值,您必须使用内存屏障。 你可以使用例如std :: atomic ,它可以为你做得很好

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM