如何通知尾部更新到 C++ 窗口中的线程? [读取全局变量的未缓存值]
Posted
技术标签:
【中文标题】如何通知尾部更新到 C++ 窗口中的线程? [读取全局变量的未缓存值]【英文标题】:How to Notify Tail updates to threads in c++ windows? [Read uncached value for globals] 【发布时间】:2019-08-14 05:19:23 【问题描述】:简介: 在下面的代码中,主函数创建 8 个线程,生产者一次填充一个有效负载数组,等待特定消费者读取它,然后移动到下一个索引。等待机制是,等待全局值被消费者清除。
//Producer
volatile int Payload[8];//global
CreateThread(); // 8 threads.
while(1)
for(int i = 0; i < 8;i++)
Payload[i] = 10;
while(Payload[i]==10); //this is done to wait till thread reads and clears it.
//Consumer
while(1)
if(Payload[threadindex])
x = Payload[threadindex];
Payload[threadindex] = 0;
cout << "print" << endl;
这不起作用。不知怎的,我被困在了
while(Payload[i]==0);
我认为问题如下。
即使我将 Payload 保持为 volatile,程序仍会从缓存中读取它,因此会获取陈旧的值。
如何强制线程取消缓存值?
我一般如何解决这个问题?我对多线程比较陌生。
更新: 我看到 *** 建议使用以下链接。
Does guarding a variable with a pthread mutex guarantee it's also not cached?
其中提到了 pthread 函数执行内存屏障以确保缓存效果对其他线程可见。
我们在 Windows 上有什么东西吗?
【问题讨论】:
你应该发布一些真实的代码,这个伪代码并不能说明整个故事。例如,我不知道 "while (Payload[i]==0); 应该告诉我什么。 更新了我的帖子。 代码不是 C,而是 C++。 更新了标签。 易失性整数是“未缓存的”。你仍然可以有竞争条件。但这不是minimal reproducible example,并且 volatile int 标志不是通知线程的正确方法。 【参考方案1】:实现生产者/消费者模型的常规方法是使用std::mutex
和std::condition_variable
:
#include <mutex>
#include <thread>
#include <iostream>
#include <condition_variable>
int main()
const size_t threadCount = 8;
int payload[threadCount];
std::condition_variable condition;
std::mutex mutex;
std::vector<std::thread> threads;
for (size_t i = 0; i < threadCount; i++)
threads.emplace_back([&, i]
while (true)
std::unique_lock lock(mutex);
// wait until payload is non-zero
condition.wait(lock, [&] return payload[i] != 0; );
int value = payload[i];
payload[i] = 0;
// tell the producer we have cleared the value
condition.notify_all();
// unlock mutex whilst we do our work to allow other threads/producer to keep running
lock.unlock();
std::cout << value << "\n";
);
while (true)
for (size_t i = 0; i < threadCount; i++)
std::unique_lock lock(mutex);
// wait until payload is zero
condition.wait(lock, [&] return payload[i] == 0; );
payload[i] = i;
// tell the consumers we have set the value
condition.notify_all();
这可以正确同步线程之间的数据,并且没有工作的线程处于空闲状态,而不是使用 100% CPU 连续检查某些工作的值。
注意负载数组不需要是易失性的。
【讨论】:
以上是关于如何通知尾部更新到 C++ 窗口中的线程? [读取全局变量的未缓存值]的主要内容,如果未能解决你的问题,请参考以下文章
从 WTL 和 C++ 中的工作线程更新 CListViewCtrl