Is a race condition possible when only one thread writes to a bool variable in c++?

a 夏天 提交于 2020-01-02 03:20:07

问题


In the following code example, program execution never ends.

It creates a thread which waits for a global bool to be set to true before terminating. There is only one writer and one reader. I believe that the only situation that allows the loop to continue running is if the bool variable is false.

How is it possible that the bool variable ends up in an inconsistent state with just one writer?

#include <iostream>
#include <pthread.h>
#include <unistd.h>

bool done = false;

void * threadfunc1(void *) {
    std::cout << "t1:start" << std::endl;
    while(!done);
    std::cout << "t1:done" << std::endl;

    return NULL;
}

int main()
{
    pthread_t threads;

    pthread_create(&threads, NULL, threadfunc1, NULL);

    sleep(1);

    done = true;
    std::cout << "done set to true" << std::endl;

    pthread_exit(NULL);

    return 0;
}

回答1:


There's a problem in the sense that this statement in threadfunc1():

   while(!done);

can be implemented by the compiler as something like:

       a_register = done;
   label:
       if (a_register == 0) goto label;

So updates to done will never be seen.




回答2:


There is really nothing that prevents the compiler from optimizing the while-loop away. Use atomic or a mutex to access the bool from more than one thread. That is the only supported and correct solution. As you are using posix, a mutex would be the right solution in this case.

And don't use volatile. There is a posix standard that states what has to work and volatile is not a solution that has a guaranty to work.

And there is an othere problem: There is no guaranty that your newly created thread every started to run, before you set the flag to false.




回答3:


Race condition means: when two threads are accessing the same object, and at least one of them is a write.

It means you will have two types of racing, write-write conflict and write-read conflict.

Back to your code, you essentially have two threads, one is the main thread, and another one is the one you created with pthread_create.

One of them is a read: while(!done), and one of them is a write: done = true.

You have race condition for sure.




回答4:


Is a race condition possible when only one thread writes to a bool variable in c++?

Yes. In your case, the main thread is also a thread (i.e. you have one thread writing and one thread reading).

How is it possible that the bool variable ends up in an inconsistent state with just one writer?

The compiler is (should be) an optimizing compiler. It will probably optimize the reading of the done variable, unless you take care to avoid that (use std::atomic<bool> done instead).




回答5:


its not guaranteed that the assignment to a bool which is one byte is atomic




回答6:


For such simple example volatile is enough. But for vast majority of real world situations it is not. Use conditional variable for this task. They look weird at the first glance but actually they are quite logical. On x86 bool IS atomic to read/write (for ARM, probably, not). Also there is an obstacle with vector: it is NOT a vector of bools, it is a bitfield. To write vector from several threads use vector (or bool arr[SIZE]). Also you don't join with thread, it is wrong.



来源:https://stackoverflow.com/questions/21183261/is-a-race-condition-possible-when-only-one-thread-writes-to-a-bool-variable-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!