仅使用 volatile 修复 DCLP
Fixing DCLP only with volatile
我正在阅读解释 DCLP 中问题的文章“C++ and the Perils of Double-Checked Locking”。
文章的第二部分(link 转发)展示了如何尝试仅使用 C/C++ volatile 来解决 DCLP(据我所知,这是不可能的)。在文章中,作者解释了如何做到这一点(最后一个例子是数字 11),但他们写道:
Unfortunately, all this does nothing to address the first
problem—C++'s abstract machine is single threaded, and C++ compilers
may choose to generate thread-unsafe code from source like that just
mentioned, anyway. Otherwise, lost optimization opportunities lead to
too big an efficiency hit. After all this, we're back to square one.
But wait, there's more—more processors.
这意味着(如果我理解正确的话),无论我们使用 volatile 多好,它都不起作用,因为“C++ 的抽象机是单线程的,C++ 编译器可能选择从源代码生成线程不安全的代码
就像刚才提到的那样"
但这意味着什么 "C++'s abstract machine is single threaded"?!
为什么上述所有这些挥发性物质的示例都不会阻止重新排序?
谢谢!
从 C++11 开始,您的粗体标记句子不再正确。
过去的意思:
OS/device 可能支持多线程,包括启动它们的函数等。
另一方面,C++ 编译器等 "think" 单线程环境,并且不知道使用多线程时可能出现的问题。线程启动只是对它们的正常函数调用,并且 OS 对进程做了一些奇怪的事情,因为该调用既不为人所知也不有趣。
单线程环境中的代码重新排序是可能的,只要重新排序的代码部分彼此独立(例如,变量的顺序 written/read to/from 使使用此变量的代码依赖).在多线程环境中,编译器不可能知道变量是否以及何时受到另一个线程...
的影响
现在,在 C++11/C++14 中,有 OS-独立支持
用于防止优化破坏线程代码。
这意味着一个线程执行的写入总是立即对其自身可见,并且将具有相同的逻辑结果,就好像代码没有被编译器或 CPU 重新排序一样,即使这可能有发生了。
被破坏的是这些写入对共享相同数据的其他线程的显示方式 space。这已在 C++11 中修复。
它还赋予了 const 和 mutable 略微不同的含义。使 class 成员可变不再像过去那样笨拙,现在当可以以线程安全的方式修改成员时使用它,即任何更改都以逻辑一致的方式对其他线程可见。例如。使 std::mutex 或 std::atomic 可变是完全没问题的,但不是普通的 int。
我正在阅读解释 DCLP 中问题的文章“C++ and the Perils of Double-Checked Locking”。
文章的第二部分(link 转发)展示了如何尝试仅使用 C/C++ volatile 来解决 DCLP(据我所知,这是不可能的)。在文章中,作者解释了如何做到这一点(最后一个例子是数字 11),但他们写道:
Unfortunately, all this does nothing to address the first problem—C++'s abstract machine is single threaded, and C++ compilers may choose to generate thread-unsafe code from source like that just mentioned, anyway. Otherwise, lost optimization opportunities lead to too big an efficiency hit. After all this, we're back to square one. But wait, there's more—more processors.
这意味着(如果我理解正确的话),无论我们使用 volatile 多好,它都不起作用,因为“C++ 的抽象机是单线程的,C++ 编译器可能选择从源代码生成线程不安全的代码 就像刚才提到的那样"
但这意味着什么 "C++'s abstract machine is single threaded"?!
为什么上述所有这些挥发性物质的示例都不会阻止重新排序?
谢谢!
从 C++11 开始,您的粗体标记句子不再正确。
过去的意思:
OS/device 可能支持多线程,包括启动它们的函数等。
另一方面,C++ 编译器等 "think" 单线程环境,并且不知道使用多线程时可能出现的问题。线程启动只是对它们的正常函数调用,并且 OS 对进程做了一些奇怪的事情,因为该调用既不为人所知也不有趣。
单线程环境中的代码重新排序是可能的,只要重新排序的代码部分彼此独立(例如,变量的顺序 written/read to/from 使使用此变量的代码依赖).在多线程环境中,编译器不可能知道变量是否以及何时受到另一个线程...
的影响现在,在 C++11/C++14 中,有 OS-独立支持
用于防止优化破坏线程代码。
这意味着一个线程执行的写入总是立即对其自身可见,并且将具有相同的逻辑结果,就好像代码没有被编译器或 CPU 重新排序一样,即使这可能有发生了。
被破坏的是这些写入对共享相同数据的其他线程的显示方式 space。这已在 C++11 中修复。
它还赋予了 const 和 mutable 略微不同的含义。使 class 成员可变不再像过去那样笨拙,现在当可以以线程安全的方式修改成员时使用它,即任何更改都以逻辑一致的方式对其他线程可见。例如。使 std::mutex 或 std::atomic 可变是完全没问题的,但不是普通的 int。