以下代码块通过lambda表达式启动线程。此lambda表达式通过引用捕获局部变量"testVar"。在线程函数执行时,该局部变量超出范围,线程函数将无法访问正确值。通过将捕获子句中的"&"更改为"=",对通过复制捕获进行了简要测试。for循环似乎打印了正确的值。我的问题是捕获发生在什么时候?是在创建lambda函数时还是在执行线程时发生?在后一种情况下,通过复制进行捕获不应该产生正确的结果。
#include <iostream>
#include <string>
#include <vector>
#include <thread>
int main()
{
std::thread myThread;
{
std::vector<int> testVar(10, 128);
std::cout<<"Trying to create thread"<<std::endl;
myThread = std::thread([&](){std::this_thread::sleep_for(std::chrono::seconds(3));for(int i=0; i<10; i++){std::cout<<testVar[i]<<std::endl;}});
}
myThread.join();
}
按引用捕获将产生以下结果
正在尝试创建线程1580344384 21851 1580269584 21851 128 128 128 128 128 128
通过拷贝捕获会产生以下结果
正在尝试创建线程128 128 128 128 128 128 128 128 128 128 128 128
1条答案
按热度按时间xxhby3vn1#
lambda是一个expression,它的值实际上是一个functional object。它在表达式求值时捕获变量,如果你把它放在同一个地方,它和任何其他表达式求值的同时发生。也就是说,它会发生在program order中。
如果我们将代码扩展一点,...
......然后对lambda求值,捕获
testVar
引用,* 在 * 程序输出“Creating the thread function”之后,* 在 * 它输出“Trying to create thread”之前。显然,这一切都发生在创建线程对象之前。