简体   繁体   中英

One thread writes to a variable the other thread reads the variable how do I (pre-C++11) protect that variable?

I'm working pre C++11 otherwise I'd just use include thread and atomic variables to fulfill my needs, however, can't do that. Got a class that when instanced starts several threads. Within a thread launched function I've got something like:

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

And another function that would be:

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

A thread will be chewing through a buffer based on indexes assigned from another thread. So one thread would assign a value that another thread would never do anything but read that value. My plan was to use more volatile memory to assign those index values. However, this question suggests I'm using volatile memory incorrectly When to use volatile with multi threading? . What is the correct way pre-C++11 to handle memory in a multithreaded class like this? Keep in mind I am not allowing more than one thread to assign a single variable while each thread may read that variable.

EDIT: Forgot to include that this is a Windows program with no need for cross platforming. I'm using afxwin.h AfxBeginThread() for my threading.

This scenario is best solved using a manual reset event object (or the corresponding CEvent MFC wrapper). When you want to terminate the thread, you simply signal the event. The thread loop should evaluate the event state:

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

Or as an MFC version:

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

The most efficient way to handle this while leaving the code as written is to use the interlocked functions:

volatile DWORD runThisThread;

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

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

This is significantly faster than using a critical section to protect the variable or replacing the variable with an event object.

(However, if your loop needs to idle, for example while waiting for more work, then you should be using an event object to avoid busy waiting.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM