Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 仅使用volatile修复DCLP_C++_Multithreading_Double Checked Locking - Fatal编程技术网

C++ 仅使用volatile修复DCLP

C++ 仅使用volatile修复DCLP,c++,multithreading,double-checked-locking,C++,Multithreading,Double Checked Locking,我正在阅读文章“”,它解释了DCLP中的问题 文章的第二部分(链接转发的地方)展示了如何尝试仅使用C/C++volatile解决DCLP(据我所知,这是不可能的)。在这篇文章中,作者解释了如何做到这一点(最后一个例子是数字11),但他们写道: 不幸的是,所有这些都无助于解决第一个问题 问题C++的抽象机器是单线程的,C++编译器 可能会选择从源代码生成线程不安全的代码,就像这样 反正我也提到过。否则,失去的优化机会将导致 对效率的打击太大了。经过这一切,我们又回到了原点。 但是等等,还有更多的处

我正在阅读文章“”,它解释了DCLP中的问题

文章的第二部分(链接转发的地方)展示了如何尝试仅使用C/C++volatile解决DCLP(据我所知,这是不可能的)。在这篇文章中,作者解释了如何做到这一点(最后一个例子是数字11),但他们写道:

不幸的是,所有这些都无助于解决第一个问题 问题C++的抽象机器是单线程的,C++编译器 可能会选择从源代码生成线程不安全的代码,就像这样 反正我也提到过。否则,失去的优化机会将导致 对效率的打击太大了。经过这一切,我们又回到了原点。 但是等等,还有更多的处理器

这意味着(如果我理解正确),我们使用Valk的方式没有多大关系,它不会起作用,因为C++的抽象机器是单线程的,C++编译器可以选择从源代码中生成线程不安全代码。 就像刚才提到的那样“

但是“C++的抽象机器是单线程的”是什么意思呢

为什么上面所有这些挥发物的例子都不能阻止重新排序


谢谢

自C++11以来,您的粗体标记语句不再正确

过去的含义:
操作系统/设备可能支持多线程,包括启动线程的功能等。
另一方面,C++编译器则是对单线程环境的“思考”,并且在使用多个线程时不知道可能出现的问题。线程启动只是对它们的一个普通函数调用,而操作系统因为这个调用而对进程做了一些奇怪的事情,这既不为人所知,也不令人感兴趣

只要重新排序的代码部分彼此独立,单线程环境中的代码重新排序是可能的(例如,变量的写入/读取顺序使得使用该变量的代码相互依赖)。在多线程环境中,编译器不可能知道一个变量是否以及何时受到另一个线程的影响

现在,在C++11/C++14中,有独立于操作系统的支持

用于防止优化破坏线程代码。

这意味着一个线程执行的写操作总是立即对其自身可见,并且具有相同的逻辑结果,就好像编译器或CPU没有对代码重新排序一样,即使可能发生了这种情况

被打破的是,这些写操作如何出现在共享相同数据空间的其他线程中。这在C++11中得到了修复


它也赋予了const和mutable稍微不同的含义。使类成员可变不再是过去的难题,现在可以在可以以线程安全的方式修改成员时使用它,即任何更改都可以以逻辑一致的方式对其他线程可见。例如,使std::mutex或std::atomic可变是完全可以的,但不是简单的int。

值得一提的是,使用C++11的std::atomic和其他并发支持,最终可以在标准C++中编写安全的双重检查锁定代码,而不使用<代码>易失性< /代码>。另一方面,程序员仍然有义务避免UB。根据标准,volatile不能提供关于线程的特别有力的保证。易变访问可以被慷慨地重新排序。是的,UB仍然是UB,没有人说别的。错误代码就是错误代码,与线程支持无关。“如果”是因为这个原因你投了反对票,那就太好笑了。(还有,我在回答中甚至没有提到volatile)我投了反对票,因为你没有提到volatile。问题在于它。