问题描述
我需要生成一堆随机数,并使用(只是读取)它们来自不同的线程。这是我生成数字的方法:
const std::vector<double>* Test::getRandomDoubles(int count)
{
std::vector<double>* numbers = new std::vector<double>();
numbers->reserve(count);
for (int i = 0; i < itemsCount; i++)
{
srand((int)std::chrono::high_resolution_clock::Now().time_since_epoch().count());
numbers->emplace_back(rand() / 1000);
}
return numbers;
}
但是我有时会丢失数字:
std::future<void> SomeMethod(const std::vector<double>& numbers)
{
return std::async( // breakpoint: numbers are available when creating the future.
std::launch::async,[&]()
{ // breakpoint: numbers gone. <-
// Use numbers
如果有帮助,我可以这样调用SomeMethod:
// Just want to run some test for SomeMethod.
std::vector<void> futures;
for(int i = 0; i < 10; i++)
{
std::vector<double> numbers = *getRandomDoubles(count);
futures.emplace_back(SomeMethod(numbers));
}
for(int i = 0; i < 10; i++)
{
futures[i].get();
}
我应该怎么做才能在异步lambda中包含数字?
解决方法
您有责任确保lambda不会超过它通过引用捕获的变量。
如果从函数返回一个lambda,则在调用它时,它已捕获的局部变量早就死了。如果异步运行它并返回future,则会发生同样的事情。
克服此问题的一种方法是通过复制或by move进行捕获。
偶然地,getRandomDoubles()
应该不调用new
并返回一个指针。 C ++不是Java。写
std::vector<double> Test::getRandomDoubles(int count) {
std::vector<double> numbers;
...
return numbers;
}
,
您捕获的向量是一个副本,而不是您动态分配的副本:
std::vector<double> numbers = *getRandomDoubles(count);
这一行完成后,原始向量将永远作为泄漏的内存消失。将numbers
用作参考以避免复制。作为警告,如果您不想将其复制或移动到异步代码中,请确保同步访问该共享可变状态。