Luc*_*ckk 9 c++ multithreading c++11
考虑以下代码:
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
std::thread t;
{
auto my_lambda = []{
int idx = 0;
while (true) {
std::this_thread::sleep_for (std::chrono::seconds(1));
std::cout << idx ++ << std::endl;
}
};
t = std::thread(my_lambda);
}
t.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
线程运行超出范围的 lambda 函数是否安全?
我看到 的构造函数std::thread
采用输入函数的通用引用Function&& f
,并且 lambda 被转换为结构。因此,如果结构体的实例在作用域内实例化,则线程将运行operator()
悬空引用。
{
struct lambda_translated { void operator()(){ ... } };
lambda_translated instance;
t = std::thread(instance);
}
Run Code Online (Sandbox Code Playgroud)
但我不确定我的推理是否正确。
附带问题:如果我在构造函数内将 lambda 声明为 R 值,行为是否会改变std::thread
:
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
std::thread t;
{
t = std::thread([]{
int idx = 0;
while (true) {
std::this_thread::sleep_for (std::chrono::seconds(1));
std::cout << idx ++ << std::endl;
}
});
}
t.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
作为评论摘要:
lambda 被复制(或者如果就地声明则被移动),因此不会出现问题。
您必须担心捕获:不要通过引用捕获可能超出范围的对象,或者如果您传递可以在线程执行期间删除的对象(即使复制,请考虑指向对象的原始指针)。
作为扩展,如果您用于std::bind
传递方法并且对象超出范围或被删除,则同样适用。