Reputation: 169
I am learning how to use thread in boost library, during my search I found the code below:
struct count
{
count(int id) : id(id) {}
void operator()()
{
for (int i = 0; i < 10; ++i)
{
boost::mutex::scoped_lock
lock(io_mutex);
std::cout << id << ": " << i << std::endl;
}
}
int id;
};
int main(int argc, char* argv[])
{
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
thrd1.join();
thrd2.join();
return 0;
}
This program works fine, but my question is, what is the behaviour of the void
operator()()
function? Because there are two threads and each one initializes the count with different values. It's two main count
variables are created seperately, so their void operator()()
should be different for each variable. But it seems that void operator()()
is the same for both threads. One more thing in this code void operator()()
is not being called from anywhere, so how it is running?
Can someone please explain me what is going on inside this function?
void operator()()
Upvotes: 1
Views: 1000
Reputation: 2138
It would certainly help fi you read the context of the code (and post a link here for other readers :)).
Without any other context to help me, I'd guess this was a demonstration for new learners of boost::thread. I'll assume you know how threads work - this link is a good beginners concepts reference if you're new.
To break it down:
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
create two threads with different Ids. As @quetzalcoatl mentions, the boost thread takes in a function object that defines the operator ()()
and executes the contents of that operator in a different thread. This means we have 3 threads now - the main execution thread and the 2 threads that we've created above.
thrd1.join();
thrd2.join();
the main execution thread waits for the other two threads to join - i.e. finish their processing and indicate to the main thread that they are done. When they join the thread is terminated (note that thrd1 is a boost thread object - used to reference the actual thread we create behind the scenes, and will be available till the stack ends).
The operator()()
is a way to monitor a. which thread is running and b. how many 'skipping-between-threads' happen. Before explaining, let's see the result. It's likely to be something like (but probably not exactly):
1: 0
1: 1
2: 0
2: 1
2: 2
2: 3
1: 2 ...
So the program (in this case) runs two loops of thread #1, switches to thread #2, runs a few loops, comes back to #1 and continues running. There is a reason both threads can't go into the loop at the same time - the boost scoped_lock grabs hold of the (external) io_mutex, locks it down for that thread's use and proceeds to run till the scoped_lock object is destroyed and the io_mutex object released. This means, while both threads are running parallelly, only one object has access to that specific stack after the "scoped_lock" call.
Hope that helps.
Upvotes: 0
Reputation: 33506
This is a tricky syntax here.
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
In those two lines, the operator()
is NOT called directly. The count(n)
visible here is the constructor. Then, the objects constructed with '1' and '2' values are passed to a thread
objects, which then internally calls operator()
to run the specific task on that different thread created for this purpose.
But since two objects remembered different values (1/2) in their ctors, the common code in operator()
operates on different actual values of id
field. That's why the operator has no parameters: all required params are stored in the 'count' object during its construction.
Btw. to construct an object and call the operator()
, a line would look like this:
count(1)();
Upvotes: 4
Reputation: 2233
The syntax of operator overloading in C++ is :
return-type operator operator-name (args); Example : int operator+(int other) Here the operator name is "+". In your case, it's "()"
Now here, you've got 2 instances of thread, each one having it's own instance of count. When the thread calls operator()(), it reads the count value of the particular instance of thread which is why you have different results for the same operator
Upvotes: 0