Using atomatics with std :: thread in C ++ 11

I have a thread that I want to sit in the loop until I can exit the program, and at what point I want it to exit the loop and exit, so I can call std::thread::join on it. In the days of C ++ 03, I would just use a lock protected bool to tell the thread when to exit. This time I thought that I would use the new Atomics library (especially std::atomic_bool ), but I have problems. Below is my test case:

 #include <atomic> #include <thread> #include <cstdio> using namespace std; void setBool(atomic_bool& ab) { ab = true; } int main() { atomic_bool b; b = false; thread t(setBool, b); t.join(); printf("Atomic bool value: %d\n", b.load()); return 0; } 

A thread t declaration splashes out this monster when trying to compile. The central part of the error is as follows:

incorrect initialization of a non-constant link of type 'std :: atomic_bool & from rvalue of type' std :: atomic_bool

Why can't I get a link to atomic_bool ? What should I do instead?

+7
source share
3 answers

You need to explicitly pass the link to your stream. Using std::ref will create std::reference_wrapper , which will be copied and wrap ref into your function.

 thread t(setBool, std::ref(b)); 

Otherwise, he will try to copy your atom, which is not in doubt.

+13
source

As bamboo explained, you should wrap objects with std::ref if you really want to be passed by reference through the variable constructor std::thread . (The same goes for std::async .) To avoid this inconsistent behavior, you can use a lambda that behaves exactly as you expected. Just use this to create the stream:

 thread t([&]{ setBool(b); }); 

With lambdas, there is no need for ref / cref nonsense when you want to pass arguments by reference.

+4
source

I also ran into this, I think you could also solve your problem by passing the address-to-atom like this:

 std::atomic<bool> b{false}; std::thread t(setBool, &b); 

If your function accepts a pointer to an atom:

 void setBool(std::atomic<bool>* ab) 

I'm not sure what the accepted practice is, I suppose you could pass a null pointer to atomic in this way, but I'm not sure why you want to.

0
source

All Articles