Reputation: 3705
I'm trying to use lambdas with threads in c++, and use captures as a way of passing data to the thread. The following code prints "ConnectionInfo(copy)" three times when the thread is created. Is there anyway to reduce it to a single copy? I'm not sure why it's copied the extra two times.
#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;
}
Output is:
Create
Thread
ConnectionInfo(copy)
ConnectionInfo(copy)
ConnectionInfo(copy)
Joining
Done
Joined
Upvotes: 0
Views: 151
Reputation: 21166
The definition of std::thread requires the arguments to be passed by value to the new thread and as the lambda is a temporary in your case, that is exactly what you want. However, those extra copies are most likely actually moves that degrade to copies, as your class doesn't have a move constructor.
So, adding a move constructor to your class, should bring down the sequence to one copy (the capture) and two moves.
Of course, this only helps, if move is cheaper than copy, but i if the overhead of a copy matters compared to the creation of the thread, your object is most likely managing some data on the heap or has to perform otherwise expensive operations on copy that often can be omitted in the move constructor.
Upvotes: 2