Answer the question
In order to leave comments, you need to log in
Because of what extra objects when passing a functor to std::thread?
Hello!
I decided to see what would be created/deleted when passing a functor to std::thread. I assumed that one copy of the original object would be created, but the result was surprising - five constructors and destructors. Tell me what and why he creates? And a passing question: is it possible to somehow pass an object with a private destructor to it (if the object is singleton)?
Compiled in VS 2012, here is the code and output:
#include <iostream>
#include <thread>
class Toster
{
public:
Toster(void)
{
std::cout << "t+ " << std::this_thread::get_id() << std::endl;
}
Toster(Toster&)
{
std::cout << "tC " << std::this_thread::get_id() << std::endl;
}
~Toster(void)
{
std::cout << "t- " << std::this_thread::get_id() << std::endl;
}
void operator()(void)
{
std::cout << "t() " << std::this_thread::get_id() << std::endl;
}
};
int main()
{
Toster test;
std::cout<< "thread start" << std::endl;
std::thread thr(test);
thr.join();
std::cout << "thread stop" << std::endl;
test();
std::cin.get();
return 0;
}
t+ 6092
thread start
tC 6092
tC 6092
tC 6092
tC 6092
tC 3924
t() 3924
t- 6092
t- 3924
t- 6092
t- 6092
t- 6092
thread stop
t() 6092
Answer the question
In order to leave comments, you need to log in
With optimization turned on, it will be much less under gcc with O3, I believe that under the MS compiler as well.
And yes, to the question of what happens: Since you do not have a move constructor, your object is copied on each operation that occurs in the std::thread constructor
. The first copying occurs already at the constructor call,
then inside std::thread copies your object into some kind of std ::function I use something like std::bind whose constructors also copy your object at each step
Optimizers usually reduce such copies to 1 two, and yes, on modern processors for a bunch of tasks it is not critical in terms of speed whether you pass a pointer to an object or just copy his
In case anyone is wondering, with the carry constructor (denoted by t&) without any additional switches, the output of gcc looks like this:
t+ 3074952016
thread start
tC 3074952016
t& 3074952016
t- 3074952016
t() 3074943856
t- 3074943856
thread stop
t() 3074952016
t+ 6092
thread start
tC 6092
t& 6092
t& 6092
t& 6092
t& 3924
t() 3924
t- 6092
t- 3924
t- 6092
t- 6092
t- 6092
thread stop
t() 6092
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question