更新:我以另一种形式提出了这个问题(见下文),但由于不具建设性而被关闭。有点遗憾,因为答案完全符合我的要求(并解决了我的问题),但我是新来的,所以我一定会再次尝试使其更具建设性。
我在 Windows 7 下使用 VC++。我的多线程程序将值分配给一个线程中的变量,然后通过事件对象将信号发送到另一个被阻塞的线程,等待该信号。由于编译器提供的优化之类的东西,不能保证一个线程分配给变量的数据实际上对另一个线程可用,即使一个线程确定(通过阻塞机制)另一个线程不会尝试访问直到数据被分配给变量之后的一段时间。例如,该值可能在 CPU 寄存器中,一直保留在那里,直到需要该寄存器用于其他用途。如果在将值放入该寄存器后不久再次需要该值,这可以避免从内存中进行不必要的加载。很遗憾,这意味着内存中的相应位置继续保存它在分配新值之前保存的最后一个值。因此,当其他线程解除阻塞并访问保存变量值的内存时,它将获得旧值,而不是最近分配的值。
那么问题是:一个 Windows 线程如何强制将其分配给变量的值存储到内存中,以便另一个线程在以后确定可以访问它们?可能有几个答案,但在这个问题结束之前提供的一个似乎最适合我需要的答案是使用“内存栅栏”,这是我以前从未听说过的编程结构。遇到栅栏后,保证已完成对内存的挂起写入。(如果栅栏是“写”栅栏;可以使用“读取”栅栏强制从内存中读取,并且可以使用“读/写”栅栏同时执行这两种操作。Windows 在 VC++ 中很容易实现这三个程序。)
一个小问题原来是 Windows 栅栏(又名“内存屏障”)仅将其保证应用于全局而非本地存储(原因在适用的 MSDN 页面上进行了解释)。
如果我在这里对记忆栅栏如何工作的解释不正确(并且版主曾经重新打开这个问题),我很高兴在评论中看到这一点。毕竟,我不会问我是否谦虚到承认我不知道。(如果版主没有重新打开它,但你可以看到我有问题,请给我发电子邮件并让我知道;我很乐意帮助在我的博客上保持这个讨论的活力,如果你这样做。)
原始版本
在线程之间共享数据的好方法是什么?
我之前问了一个关于volatile
变量的问题,这些变量为我带来了巨大的学习经验。除其他外,我意识到我没有问对正确的问题。希望这不是坏的stackoverflow礼仪,但我认为我应该在这里创建一个新问题来解决我的潜在问题:
我的 Visual C++ 程序中有两个线程 A 和 B。B 被阻塞,等待来自 A 的信号。A 设置了许多变量。A 然后向 B 发出信号,B 将读取 A 设置的变量。我担心 A 设置的某些变量实际上可能不会写回内存,因为它们可能只驻留在 CPU 寄存器中。
什么是确保线程 B 在读取线程 A 先前设置的变量时读取线程 A 设置的值的好方法?