boost::thread on member function

We have already seen how to create threads running on free functions and on functors. Now we are about to see how to run threads on member functions.

Have a look at this class:

class Multi
{
private:
boost::mutex mx_;
int value_;
public:
Multi(int value) : value_(value) { }

int getValue() { return value_; }

void increase()
{
for(int i = 0; i < 3; ++i)
{
{
boost::lock_guard<boost::mutex> lock(mx_);
std::cout << "Thread " << boost::this_thread::get_id()
<< ": " << ++value_ << std::endl;
}
boost::this_thread::sleep(boost::posix_time::millisec(50));
}
}

void divide(int div)
{
for(int i = 0; i < 3; ++i)
{
{
boost::lock_guard<boost::mutex> lock(mx_);
std::cout << "Thread " << boost::this_thread::get_id()
<< ": " << (value_ /= div) << std::endl;
}
boost::this_thread::sleep(boost::posix_time::millisec(50));
}
}
};

We have a couple of methods, increase() and divide(), competing on a resource, value_, whose access is ruled by the mutex mx_. Actually, mx_ is used to protect the access to both value_ and std::cout - in this case there was no need of a dedicate mutex for each resource. As usual, the mutex is acquired and released by a lock.

And here a simple function using that class:

void mt05()
{
Multi m(42);
std::cout << "Main thread " << m.getValue() << std::endl;

boost::thread t1(&Multi::increase, &m); // 1.
boost::thread t2(&Multi::divide, &m, 2); // 2.
t1.join();
t2.join();
std::cout << "Main thread: " << m.getValue() << std::endl;
}

1. Here the thread constructor is expecting a callable as first parameter, and this is no news, so we pass it the address of a member function. But now we have to say to the thread to which actual object it should refer, so we pass it the "this" pointer of that object.
2. Same as the previous line, but here we need to pass a value to be used as input parameter to divide().

No comments:

Post a Comment