[英]How to properly pass variable to lambda function in thread
我在这段代码中泄漏。 我知道我错误地将对象传递给vector和lambda函数,但是我不确定如何解决这个问题。 您能否给我任何代码审查和更正?
std::vector<std::thread> threads;
std::vector<std::unique_ptr<FileHandler>> fileHandlers;
for (std::string argument : filesToParse)
{
std::unique_ptr<FileHandler> fileHandler(new FileHandler(argument));
fileHandlers.push_back(std::move(fileHandler));
threads.push_back(std::thread([&fileHandler]()
{
fileHandler->processFile();
}));
}
for(auto i = 0; i < threads.size(); ++i)
{
threads.at(i).join();
fileHandlers.at(i)->mergeMaps(finalMap);
}
所示逻辑存在多个问题。
fileHandlers.push_back(std::move(fileHandler));
fileHandler
unique_ptr的内容已移至此处。 在此之后立即:
threads.push_back(std::thread([&fileHandler]() {
这会向每个新线程传递对unique_ptr
的引用,其内容刚刚从移走了 。 这个unique_ptr
已经不见了它的制造商。 它不再存在。 加入了看不见的合唱团。 这是一个ex- unique_ptr
。
fileHandlers.push_back(std::move(fileHandler));
回到这句话。 您会在这里得到两个逻辑错误,价格为一。
fileHandlers
是一个向量。 向向量添加值可能会重新分配向量。 重新分配会使所有现有的迭代器,指针或对向量的现有内容的引用无效。 传递对该向量中某物的引用,然后在循环的下一次迭代中向该向量中添加某物,如果向量重新分配,则会在您的面前大怒。
这里的明显意图是用所有线程的所有参数的列表填充fileHandlers
向量。 正确执行此操作有两种基本方法:
使用reserve()
确保随后不会发生重新分配。
首先使用所有值填充向量,然后再生成所有线程,将现在完整的向量中对其自身参数的引用传递给每个线程。
您有几种方法可以解决这些问题:
首先填充向量,或保留其内容,然后将不是fileHandler
unique_ptr传递给每个线程,而是传递对已经填充的fileHandlers
数组中的unique_ptr
的引用。
或者,可以通过切换到shared_ptr
并按值捕获每个线程的shared_ptr
参数来避免保留或预先填充向量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.