C++内存模型 - 此示例是否包含数据竞争?

 UU常璐图_302 发布于 2023-02-07 10:57

我正在阅读Bjarne Stroustrup的C++ 11 FAQ,我无法理解内存模型部分中的示例.

他给出了以下代码片段:

// start with x==0 and y==0
if (x) y = 1; // thread 1
if (y) x = 1; // thread 2

FAQ说这里没有数据竞争.我不明白.内存位置x由线程1读取并由线程2写入而没有任何同步(并且同样适用y).这是两次访问,其中一次是写入.这不是数据竞争的定义吗?

此外,它说"每个当前的C++编译器(我所知道的)给出了正确答案." 这个正确答案是什么?根据一个线程的比较是在另一个线程的写入之前或之后发生(或者另一个线程的写入是否对读取线程可见),答案是否会有所不同?

2 个回答
  • 内存位置x由线程2写入

    是真的吗?你为什么这么说?

    如果y是0,则x按线程2.写入并y同样开出0,x不能非零除非在某种程度上y是非零"之前"线程1下运行,并且不能发生.这里的一般观点是,不执行的条件写入不会导致数据竞争.

    不过,这是内存模型的一个重要事实,因为不允许线程编译的编译器(假设y不是易失性的)将代码转换if (x) y = 1;int tmp = y; y = 1; if (!x) y = tmp;.然后有是数据的比赛.我无法想象为什么它会想要进行那种确切的转换,但这并不重要,重点是非线程环境的优化器可以做违反线程内存模型的事情.因此,当Stroustrup说他所知道的每个编译器给出了正确的答案时(就在C++ 11的线程模型下,就是这样),这是关于C++ 11线程编译器准备就绪的一个非平凡的陈述.

    if (x) y = 1将是一个更现实的转变y = x ? 1 : y;.我相信这导致您的示例中的数据竞争,并且在分配的标准中没有特殊处理,y = y这使得对于y在另一个线程中的读取执行不安全而言是安全的.您可能会发现很难想象它不起作用的硬件,无论如何我可能是错的,这就是为什么我使用上面不同的例子,这不太现实,但有一个明显的数据竞争.

    2023-02-07 10:59 回答
  • // start with x==0 and y==0
    if (x) y = 1; // thread 1
    if (y) x = 1; // thread 2
    

    既然x和y都不是真的,另一个也不会被设置为真.无论执行指令的顺序如何,(正确)结果总是x保持为0,y保持为0.

    2023-02-07 10:59 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有