What we can do with a lock_guard is just acquiring ownership of a mutex (actually, a Lockable) when constructing it and waiting its exiting of scope to have the mutex released by the destructor.
The scoped_lock, actually a typedef for unique_lock, is a more complex concept. A couple of useful functions available for this class are lock()/unlock() that allow to have a better control on locking.
The basic behavior provided by lock_guard suffices for large part of the cases, so it is better to stick to it as default, and use scoped_lock - or even some other more powerful lock - when we have complex requirements.
As example of lock_guard usage I rewrite a short test from a previous post, where originally a scoped_lock was used (even though it was not necessary):
#include <iostream>
#include "boost/thread/thread.hpp"
#include "boost/thread/locks.hpp"
using std::cout;
using std::endl;
namespace
{
boost::mutex mio;
class Count
{
private:
int multi_;
public:
Count(int multi) : multi_(multi) { }
void operator()()
{
for(int i = 0; i < 5; ++i)
{
boost::lock_guard<boost::mutex> lock(mio);
std::cout << "Thread " << boost::this_thread::get_id() << " is looping: " << i*multi_ << std::endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
}
}
};
}
void t05()
{
std::cout << "Main thread " << boost::this_thread::get_id() << std::endl;
boost::thread t1(Count(1));
{
boost::lock_guard<boost::mutex> lock(mio);
std::cout << "Thread 1 started" << std::endl;
}
boost::thread t2(Count(-1));
{
boost::lock_guard<boost::mutex> lock(mio);
std::cout << "Thread 2 started" << std::endl;
}
boost::thread t3(Count(10));
{
boost::lock_guard<boost::mutex> lock(mio);
std::cout << "Thread 3 started" << std::endl;
}
t1.join();
t2.join();
t3.join();
std::cout << "Back to the main thread " << std::endl;
}
No comments:
Post a Comment