【发布时间】:2014-11-22 01:19:31
【问题描述】:
我知道 C++ 中的 volatile 与 Java 中的含义不同,所以如果我正在为 Windows 编写 C++ 应用程序,如何在两个线程之间共享一个变量并且不允许让每个线程缓存自己的变量副本? 使用临界区能解决这个问题还是只允许原子性?
【问题讨论】:
标签: c++ multithreading winapi
我知道 C++ 中的 volatile 与 Java 中的含义不同,所以如果我正在为 Windows 编写 C++ 应用程序,如何在两个线程之间共享一个变量并且不允许让每个线程缓存自己的变量副本? 使用临界区能解决这个问题还是只允许原子性?
【问题讨论】:
标签: c++ multithreading winapi
实际上,在 Visual Studio 中,volatile 的含义与 Java(或 C#)中的含义几乎相同。或者至少,它曾经并且默认情况下仍然如此;详情请见Microsoft's documentation。
也就是说,在标准 C++ 中,volatile 确实几乎没有任何意义。此外,用标准术语来说,线程不会“缓存”任何东西,而且您的问题格式不正确。相关的概念是atomicity 和ordering,后者的标准术语是“happens-before”关系。设计、实现和推理多线程算法所需的一切都包含在这些概念中; “缓存”的概念与它无关。
标准 C++11 提供了许多机制来强制执行原子性和排序。如果您提出有关实现特定算法的特定问题,您将得到更好的答案。
[更新,澄清]
请注意,我并不是说您使用了错误的术语;我是说你使用了错误的概念。
标准没有用不同的词谈论“缓存变量”......它根本没有谈论缓存变量。那是因为这个概念对于推理线程来说既非必要也不充分。你可以对缓存一无所知,但仍然无法分析并发算法,你对缓存一无所知,却能够完美地分析它们。
同样,“直接访问变量”不仅仅是错误的说法;这个概念在(标准)C++ 中是没有意义的。当每个线程以不同的速度进行并以不同的顺序观察状态变化时,“立即执行”的概念毫无意义。在标准 C++ 中,根本没有“直接访问”或“立即访问”;只有发生在之前。
这不是学术观点。错误的并发思维模型几乎肯定会导致思维模糊和草率、错误的代码。
您的问题确实没有像措辞那样的答案。正确的答案可能是使用std::atomic 或使用std::mutex 或使用std::atomic_thread_fence,具体取决于您实际尝试执行的操作。我建议你问一个清楚说明那是什么的问题。
【讨论】:
volatile。