user3360398
user3360398

Reputation:

c++ call thread constructor

I was reading concurrency in action and came up with this piece of code. However, i dont quite understand why line<1> is syntax valid. Also, how the order got determined? is it possible to put std::thread t(&my_x, &X::do_lengthy_work); instead? how many inputs can take based on the code over here?

class X
{
public:
void do_lengthy_work();
};

X my_x;
std::thread t(&X::do_lengthy_work,&my_x);  //<1>   the bood says This code will invoke my_x.do_lengthy_work() on the new thread, because the address of my_x is supplied as the object pointer

Upvotes: 0

Views: 1556

Answers (3)

Christophe
Christophe

Reputation: 73366

Excellent book about the topic !

std::thread t(...); creates a thread object t. The first argument of the constructor must be either the adress of a function, or an executable class (i.e. a class with operator() defined).

For ordinary functions like void f(){... }, it would be sufficient to give its name as first argument f. For member function, you have to give its full name, so here: X::do_lengthy work. But for getting the pointer to the mbmer function an explicit & is required (see C++11 standard, section 5.3.1, pt 4).

The arguments following the first arguments will be given to the function when the thread starts and wants to execute it. In the specific case of member functions, the very first argument will be used to say on which object the function has to be executed.

So roughly speaking thread(&class::member_function, arg1, arg2, ... arg n) will call arg1.member_function (arg2, .... arg n).

Upvotes: 2

quantdev
quantdev

Reputation: 23793

I think that you are confused by the syntax here.

This is just a constructor call for an object of type std::thread named t (so the arguments order did not "get determined", it is defined by the constructor signature).

Two parameters are expected by this constructor :

1) A callable : &X::do_lengthy_work , as a pointer to a member function, is a Callable.

2) The arguments expected by the Callable : a member function always has an implicit this argument of type (const) X* : this is why here you pass &my_x, the address of the object on which the Callable will be called.

If you add an argument to do_lengthy_work, then you need to specify it when you construct the thread as well :

class X
{
public:
   void do_lengthy_work(int i) {}
};

int main() {
   X my_x;
   std::thread t(&X::do_lengthy_work,&my_x, 2);
                                          ^^^^
}

Upvotes: 3

Slava
Slava

Reputation: 44238

Also, how the order got determined? is it possible to put std::thread t(&my_x, &X::do_lengthy_work); instead?

As with any other c++ function order determined by function signature, in this case std::thread constructor signature:

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );

from std::thread documentation

As you can see that Function is the first parameter and parameters follow (if any). So you cannot put pointer to class before pointer to method.

Upvotes: 2

Related Questions