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