S
S
StpMax2014-03-01 14:41:15
C++ / C#
StpMax, 2014-03-01 14:41:15

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;
}

Conclusion:
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

2 answer(s)
I
Ivan Starkov, 2014-03-01
@StpMax

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

S
StpMax, 2014-03-02
@StpMax

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

and VS2012 like this:
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 question

Ask a Question

731 491 924 answers to any question