就我而言,我使用std :: future作为返回类型,但获得了未定义的行为。 代码如下:
#include <future>
#include <iostream>
#include <pthread.h>
std::future<bool> update() {
int c = 1;
//std::cout << "?" << c << std::endl; // debug line
auto lambda = [&] () -> bool {
int b = 0;
for(int i = 0; i < 10000000; ++i) {
b += 1;
}
std::cout << "?" << c << std::endl;
return c == 1;
};
return std::async(std::launch::async, lambda);
}
int main(int argc, char *argv[])
{
auto f2 = update();
std::cout << f2.get() << std::endl;
return 0;
}
我按g++-4.7.2 -std=c++11 test_future.cc -lpthread
编译了这段代码并得到以下输出结果:
?0
0
但是当我取消注释上面的debug line
时,输出变为1
(正如预期的那样)。此外,如果我使用std::future
作为update
函数的参数而不是返回值,我也可以得到正确的输出结果。
我想知道这里的问题是什么。 g ++的错误或使用的错误?感谢。
答案 0 :(得分:4)
问题是你通过引用捕获变量c
,并结合异步运行lambda。最后一部分意味着update
函数可能在lambda实际运行之前返回,现在它引用了一个不再存在的变量。
如果您有调试行,似乎的原因是因为未定义的行为。
因此问题与您返回std::future
没有任何关系。
显而易见的解决方案当然是按值捕获c
,如果在实际代码中不可能,则可能需要重新考虑您的设计。
答案 1 :(得分:0)
问题是你的lambda auto lambda = [&] () -> bool
是通过引用捕获的。对c的引用可能是悬空,因为线程可以在函数退出后执行。
您可能应该按价值auto lambda = [=] () -> bool
进行捕捉。
答案 2 :(得分:0)
对我来说,这看起来像是未定义的行为。您通过引用捕获c
,但在lambda
执行时它将超出范围。
因此c == 1
是未定义的行为,因为c
已超出范围。如果您按值捕获,那么您应该没问题。
auto lambda = [c] () -> bool {
int b = 0;
for(int i = 0; i < 10000000; ++i) {
b += 1;
}
std::cout << "?" << c << std::endl;
return c == 1;
};