Considering the following code:
#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;
}
Is it safe that the thread runs a lambda function that goes out of scope?
I saw that the constructor of std::thread
takes an universal reference for the input function Function&& f
and that lambdas are translated into structs. So if the instance of the struct is instantiated inside the scope, the thread will be running the operator()
of a dangling reference.
{
struct lambda_translated { void operator()(){ ... } };
lambda_translated instance;
t = std::thread(instance);
}
However I'm not sure that my reasoning is correct.
Side question: does the behavior change if I declare the lambda as an R-value inside the std::thread
constructor:
#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;
}
As a summary of the comments:
The lambda is copied (or moved if declared in-place), so you won't have problems.
You have to worry about the captures: do not capture by reference objects that can go out of the scope, or if you pass objects that can be deleted during thread execution (even if copied, think about a raw pointer to an object).
As an extension, same applies if you use std::bind
to pass a method and the object goes out of scope or it is deleted.
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.