Reputation: 330
#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?
Upvotes: 0
Views: 65
Reputation: 29009
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.
Upvotes: 2