c++ - 在线程中运行 lambda 时如何减少拷贝?

标签 c++ multithreading lambda

我正在尝试在 C++ 中将 lambda 与线程一起使用,并使用捕获作为将数据传递给线程的一种方式。以下代码在创建线程时打印了三次“ConnectionInfo(copy)”。有没有办法将它减少到一个拷贝?我不确定为什么要多复制两次。

#include <iostream>
#include <functional>
#include <memory>
#include <thread>

using namespace std;

class ConnectionInfo
{
public:
    ConnectionInfo():port(0) {}
    ConnectionInfo(int p):port(p) {}
    ConnectionInfo(const ConnectionInfo &other) 
    {
        std::cout << "ConnectionInfo(copy)" << std::endl;
        port = other.port;
    }

    int port;
    void Connect() {};

};


int main() {

    std::cout << "Create" << std::endl;
    ConnectionInfo c(2);


    std::cout << "Thread" << std::endl;
    std::thread t(
    [a = c]() mutable
    { 
        a.Connect();
        std::cout << "Done" << std::endl;
    }
    );

    std::cout << "Joining" << std::endl;
    t.join();
    std::cout << "Joined" << std::endl;

    return 0;
}

输出是:

Create
Thread
ConnectionInfo(copy)
ConnectionInfo(copy)
ConnectionInfo(copy)
Joining
Done
Joined

最佳答案

std::thread 的定义要求将参数按值传递给新线程,因为 lambda 在您的情况下是临时的,这正是您想要的。但是,这些额外的拷贝很可能实际上是降级为拷贝的移动,因为您的类没有移动构造函数。

因此,向您的类添加一个移动构造函数,应该将序列减少到一个拷贝(捕获)和两个移动。

当然,这只会在移动比复制便宜的情况下有所帮助,但是如果与线程的创建相比复制的开销很重要,则您的对象很可能在堆上管理一些数据或者必须执行其他操作在移动构造函数中通常可以省略的拷贝上的昂贵操作。

关于c++ - 在线程中运行 lambda 时如何减少拷贝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51368321/

相关文章:

C++构造函数隐式转换没有发生

c++ - C++中的命名空间如何链接?

c++ - 虚拟继承——gcc 与 vc++

linux - Matlab 2011a 使用 64 位 Linux 上可用的所有内核?

java - 数字数字的递归总和(直到数字小于 10)仅限 java 8 lambdas

c# - 在运行时检查属性类型并将相同的类型赋予通用 lambda 表达式参数 T

c++什么进程正在监听windows中的某个端口

multithreading - Windows XP 上的线程

java - 如何通过命令行列出java程序的默认和可用的线程调度程序?

vb.net - 通过 VB 中的 API 实现 LINQ 表达式到表达式树