一个线程写入变量,另一个线程读取变量我如何(pre-C ++ 11)保护该变量?

时间:2016-10-19 14:07:02

标签: c++ windows multithreading mfc c++03

我正在使用C ++ 11,否则我只是使用包含线程和原子变量来满足我的需求,但是,不能这样做。得到一个类,当instanced启动几个线程。在线程启动函数中我有类似的东西:

void ThisClass::ThisThread()
{
    while (runThisThread)
    {
        // doing stuff
    }
}

另一个功能是:

void ThisClass::StopThisThread()
{
    runThisThread = false; // 'runThisThread' variable is 'volatile bool'
}

线程将根据从另一个线程分配的索引来咀嚼缓冲区。所以一个线程会分配一个值,另一个线程永远不会做任何事情,只读取该值。我的计划是使用更多易失性内存来分配这些索引值。但是,这个问题表明我错误地使用了易失性内存When to use volatile with multi threading?。在这样的多线程类中,前C ++ 11处理内存的正确方法是什么?请记住,我不允许多个线程分配单个变量,而每个线程都可以读取该变量。

编辑:忘了包含这是一个不需要跨平台的Windows程序。我正在使用afxwin.h AfxBeginThread()来进行线程化。

2 个答案:

答案 0 :(得分:3)

使用手动重置event object(或相应的CEvent MFC包装器)可以最好地解决此问题。如果要终止线程,只需发出事件信号即可。线程循环应该评估事件状态:

while( ::WaitForSingleObject( hEvent, 0 ) == WAIT_TIMEOUT ) {
    // doing stuff
}

或者作为MFC版本:

while( !myEvent.Lock( 0 ) ) {
    // doing stuff
}

答案 1 :(得分:0)

在保持代码写入的同时处理此问题的最有效方法是使用互锁函数:

volatile DWORD runThisThread;

void ThisClass::ThisThread()
{
    while (InterlockedCompareExchange(&runThisThread, 0, 0))
    {
        // doing stuff
    }
}

void ThisClass::StopThisThread()
{
    InterlockedExchange(&runThisThread, false);
}

这比使用临界区保护变量或用事件对象替换变量要快得多。

(但是,如果您的循环需要空闲,例如在等待更多工作时,那么您应该使用事件对象以避免繁忙等待。)