#include <iostream>
#include <thread>
class MyClass {
public:
MyClass(int val) : val_(val) {}
int val_{0};
};
void threadFunction(MyClass myObj) {
// do something ...
}
int main() {
MyClass obj(42);
std::thread t1(threadFunction, obj);
std::thread t2([=]() {
threadFunction(obj);
});
t1.join();
t2.join();
return 0;
}
In thread t1
, I called threadfunction
directly whereas in thread t2
, I put the call of threadFunction
in a lambda.
Are these two ways of thread creation equivalent?
The only difference between the alternatives is related to copies or moves of the MyClass obj
object.
It can be observed by adding copy and move constructors with prints:
class MyClass {
public:
MyClass(int val) : val_(val) {}
MyClass(MyClass const & other)
{
std::cout << "copy\n";
val_ = other.val_;
}
MyClass(MyClass && other)
{
std::cout << "move\n";
val_ = other.val_;
}
int val_{0};
};
In the first case, the std::thread
constructor will make a copy of obj
, and then it will be moved when the function will be invoked by the new thread.
See demo1, with output:
copy
move
In the second case, there will be an additional copy when the lambda will be executed and will call threadFunction
.
See demo2, with output:
copy
move
copy
A third alternaive is the use the lambda with capture by reference.
This will reduce it to only one copy (when the lambda will call threadFunction
).
See demo3, with output:
copy
Note that this third option relies on the fact that obj
is not destroyed while the thread is being launched (otherwise a race condition will occue). In your case it is OK because the threads are join
ed while obj
is still alive.