一个线程写入一个变量,另一个线程读取该变量我(C++11 之前)如何保护该变量?
One thread writes to a variable the other thread reads the variable how do I (pre-C++11) protect that variable?
我在 C++11 之前工作,否则我只会使用包含线程和原子变量来满足我的需要,但是,不能那样做。得到一个 class 实例化时启动多个线程。在一个线程启动函数中,我有类似的东西:
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 之前的多线程 class 中处理内存的正确方法是什么?请记住,我不允许多个线程分配一个变量,而每个线程都可以读取该变量。
编辑:忘记包括这是一个不需要跨平台的 Windows 程序。我正在使用 afxwin.h AfxBeginThread() 进行线程处理。
这种情况最好使用手动重置 event object (or the corresponding CEvent MFC 包装器来解决)。当你想终止线程时,你只需发出事件信号。线程循环应该评估事件状态:
while( ::WaitForSingleObject( hEvent, 0 ) == WAIT_TIMEOUT ) {
// doing stuff
}
或作为 MFC 版本:
while( !myEvent.Lock( 0 ) ) {
// doing stuff
}
在保留代码不变的情况下处理此问题的最有效方法是使用互锁函数:
volatile DWORD runThisThread;
void ThisClass::ThisThread()
{
while (InterlockedCompareExchange(&runThisThread, 0, 0))
{
// doing stuff
}
}
void ThisClass::StopThisThread()
{
InterlockedExchange(&runThisThread, false);
}
这比使用临界区保护变量或用事件对象替换变量要快得多。
(但是,如果您的循环需要空闲,例如在等待更多工作时,那么您应该使用事件对象来避免忙等待。)
我在 C++11 之前工作,否则我只会使用包含线程和原子变量来满足我的需要,但是,不能那样做。得到一个 class 实例化时启动多个线程。在一个线程启动函数中,我有类似的东西:
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 之前的多线程 class 中处理内存的正确方法是什么?请记住,我不允许多个线程分配一个变量,而每个线程都可以读取该变量。
编辑:忘记包括这是一个不需要跨平台的 Windows 程序。我正在使用 afxwin.h AfxBeginThread() 进行线程处理。
这种情况最好使用手动重置 event object (or the corresponding CEvent MFC 包装器来解决)。当你想终止线程时,你只需发出事件信号。线程循环应该评估事件状态:
while( ::WaitForSingleObject( hEvent, 0 ) == WAIT_TIMEOUT ) {
// doing stuff
}
或作为 MFC 版本:
while( !myEvent.Lock( 0 ) ) {
// doing stuff
}
在保留代码不变的情况下处理此问题的最有效方法是使用互锁函数:
volatile DWORD runThisThread;
void ThisClass::ThisThread()
{
while (InterlockedCompareExchange(&runThisThread, 0, 0))
{
// doing stuff
}
}
void ThisClass::StopThisThread()
{
InterlockedExchange(&runThisThread, false);
}
这比使用临界区保护变量或用事件对象替换变量要快得多。
(但是,如果您的循环需要空闲,例如在等待更多工作时,那么您应该使用事件对象来避免忙等待。)