[英]Using atomics with std::thread in c++11
I have a thread that I want to sit in a loop until I'm ready to exit the program, at which point I want it to break out of the loop and exit so I can call std::thread::join
on it. 我有一个线程,我想坐在循环中,直到我准备退出程序,此时我希望它突破循环并退出所以我可以调用
std::thread::join
。 In the days of c++03, I would just use a bool protected by a lock in order to tell the thread when to exit. 在c ++ 03的时代,我只会使用一个受锁保护的bool来告诉线程什么时候退出。 This time I thought I would take advantage of the new atomics library (specifically
std::atomic_bool
), but I'm having trouble. 这次我以为我会利用新的原子库(特别是
std::atomic_bool
),但我遇到了麻烦。 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;
}
The declaration of thread t
spits out this monstrosity when I try to compile. 当我尝试编译时,
thread t
的声明吐出了这个怪异。 The central part of the error seems to be: 错误的核心部分似乎是:
invalid initialization of non-const reference of type 'std::atomic_bool&' from an rvalue of type 'std::atomic_bool'
从'std :: atomic_bool'类型的右值开始无效初始化'std :: atomic_bool&'类型的非const引用
Why can I not get a reference to an atomic_bool
? 为什么我不能获得对
atomic_bool
的引用? What should I do instead? 我该怎么做呢?
You have to explicitly pass a ref to your thread. 您必须显式地将ref传递给您的线程。 Using
std::ref
will create a std::reference_wrapper
which is copyable and will carry the ref to your function. 使用
std::ref
将创建一个可复制的std::reference_wrapper
,它将把ref带到你的函数中。
thread t(setBool, std::ref(b));
Otherwise it will try to copy your atomic, which is uncopyable. 否则它会尝试复制你的原子,这是不可复制的。
As bamboon explained, you have to wrap objects with std::ref
if you really want them to be passed by reference via std::thread
's variable-argument constructor. 正如bamboon所解释的那样,你必须用
std::ref
包装对象,如果你真的希望它们通过std::thread
的variable-argument构造函数通过引用传递。 (The same applies to std::async
.) To avoid this counterintuitive behavior, you can use a lambda, which behaves precisely as you would expect. (这同样适用于
std::async
。)为了避免这种违反直觉的行为,您可以使用lambda,它的行为与您期望的完全相同。 Just use this to create the thread: 只需使用它来创建线程:
thread t([&]{ setBool(b); });
With lambdas, there is no need for the ref/cref nonsense when you want to pass arguments by reference. 使用lambdas,当你想通过引用传递参数时,不需要ref / cref废话。
I just ran into this as well, I think you could also solve your problem by passing an address-to the atomic like so: 我也遇到了这个问题,我认为你也可以通过将地址传递给原子来解决你的问题:
std::atomic<bool> b{false};
std::thread t(setBool, &b);
Where your function takes a pointer to the atomic: 你的函数获取指向原子的指针:
void setBool(std::atomic<bool>* ab)
I'm not sure what the accepted practice is, I suppose you could pass a null pointer to the atomic this way but I'm not sure why you would want to. 我不确定接受的做法是什么,我想你可以通过这种方式将空指针传递给原子,但我不确定你为什么要这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.