繁体   English   中英

如何在线程中正确将变量传递给lambda函数

[英]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向量。 正确执行此操作有两种基本方法:

  1. 使用reserve()确保随后不会发生重新分配。

  2. 首先使用所有值填充向量,然后再生成所有线程,将现在完整的向量中对其自身参数的引用传递给每个线程。

您有几种方法可以解决这些问题:

  1. 首先填充向量,或保留其内容,然后将不是fileHandler unique_ptr传递给每个线程,而是传递对已经填充的fileHandlers数组中的unique_ptr的引用。

  2. 或者,可以通过切换到shared_ptr并按捕获每个线程的shared_ptr参数来避免保留或预先填充向量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM