首页 > 解决方案 > 如何在 lambda 函数中使用 std::move 传递值

问题描述

首先,如果时间过长,我深表歉意,因为问题可以很快得到详细说明,但是,我描述了环境的很大一部分可能会来提供帮助。

我正在用 C++ 开发一个分析基因组数据(特别是 FASTQ 数据)的工具。如果您不知道,FASTQ 文件包含基因序列的原始读数,其中该文件的每组 4 行代表基因组的读数。好吧,由于读取的处理不依赖于其他读取(在我的情况下),我打算将工作与线程并行化以节省处理时间。

搜索时,我发现一些库已经准备好,我正在尝试适应。现在我正在尝试使用线程池(特别是这个库 -> https://github.com/log4cplus/ThreadPool/),但我在集成时遇到了一些问题。

我将详细介绍一般算法。FASTQ 文件中的每次迭代都从文件中获取一组 4 行并将其存储在此结构中。

struct READ  {
            std::string name; // Small size
            std::string comment; // Small size
            std::string seq; // String ranging between 0 and 1000 characters
            std::string which; // The same amount of 'seq' characters  
};

这会立即作为一个值传递给外部函数,以执行由线程池管理的(非平凡的)任务。

ThreadPool pool (4); // Creating thread pool with 4 threads

while (exist_read) // as long as there are reads to be processed -> read set of 4 lines
{
  Read read;
  read = next_read (); // read will contain 4 lines of the file read in the iteration
  pool.enqueue ([read] {
    Search (read); // search function performs non-trivial search work
  });
}

可以看出,我在 lambda 函数中传递了值,并用多个线程对其进行了测试,但最终在使用单线程时性能较差。所以有人建议我使用可移动的物体。在极大的帮助下,我得到了这个结构。

struct READ
{
    READ () = default;
    READ (READ &&) = default;
    READ & operator = (READ &&) = default;
    std::string name;
    std::string comment;
    std::string seq;
    std::string which;
};

并且 lambda 函数已更改为:

pool.enqueue ([r {std::move(read)}] {
   Search (std::move(r));
});

此外,确实更新了 FASTQ 文件的读取:

[...]
Read read;
read.name = lines[0];
read.seq = lines[1];
read.comment = lines[2];
read.qual = lines[3];
[...]

至:

[...]
Read read;
read.name = std::move(lines [0]);
read.seq = std::move(lines [1]);
read.comment = std::move(lines [2]);
read.qual = std::move(lines [3]);
[...]

但是,我仍然无法测试性能,因为我有以下print_error

错误:无法引用函数“READ::READ (const READ &)”(隐式声明) - 它是已删除的函数 C / C ++ (1776)

我搜索了其他论坛,但找不到适合我问题的答案。如果有人可以帮助我解决这个问题,我将不胜感激。我希望我已经清楚了。此外,我也接受其他替代方案的建议。

谢谢。

标签: c++multithreadingparallel-processing

解决方案


推荐阅读