::thread另一个重要组成部分是mutexQ以?qing)工作在mutex上的boost::mutex::scoped_lock、condition和barrierQ这些都是ؓ(f)实现U程同步提供的?br />
mutex
boost提供的mutex?font color="#999900">6U:(x)
boost::mutex
boost::try_mutex
boost::timed_mutex
boost::recursive_mutex
boost::recursive_try_mutex
boost::recursive_timed_mutex
下面仅对boost::mutexq行分析?br />
mutexcL一个CriticalSectionQ(f)界区Q封装类Q它在构造函C新徏一个(f)界区qInitializeCriticalSectionQ然后用一个成员变?font color="#ff6633">
void* m_mutex;
来保存该临界区结构?br />
?
此之外,mutexq提供了do_lock、do_unlock{方法,q些Ҏ(gu)分别调用EnterCriticalSection?
LeaveCriticalSection来修Ҏ(gu)员变量m_mutexQCRITICAL_SECTIONl构指针Q的状态,但这些方法都?font color="#990000">private的,以防止我们直接对mutexq行锁操作,所有的锁操作都必须通过mutex的友元类detail::thread::lock_ops<mutex>来完成,比较有意思的是,lock_ops的所有方法:(x)lock、unlock、trylock{都?font color="#990000">static的,如lock_ops<Mutex>::lock的实玎ͼ(x)
1 template <typename Mutex>
2 class lock_ops : private noncopyable
3 {
4 
5 public:
6 static void lock(Mutex& m)
7 {
8 m.do_lock();
9 }
10 
11 }
boost::thread的设计者ؓ(f)什么会(x)q么设计呢?我想大概是:(x)
1、boost::thread的设计者不希望被我们直接操作mutexQ改变其状态,所以mutex的所有方法都?font color="#990000">private的(除了构造函敎ͼ析构函数Q?font color="#999900">
2、虽然我们可以通过lock_ops来修改mutex的状态,如:(x)
1 #include <boost/thread/thread.hpp>
2 #include <boost/thread/mutex.hpp>
3 #include <boost/thread/detail/lock.hpp>
4
5 int main()
6 {
7 boost::mutex mt;
8 //mt.do_lock(); // Error! Can not access private member!
9
10 boost::detail::thread::lock_ops<boost::mutex>::lock(mt);
11
12 return 0;
13 }
但是Q这是不推荐的,因ؓ(f)mutex、scoped_lock、condition、barrier是一套完整的cȝQ它们是怺协同工作的,像上面这么操作没有办法与后面的几个类协同工作?br />
scoped_lock
上面说过Q不应该直接用lock_ops来操作mutex对象Q那么,应该用什么呢Q答案就是scoped_lock。与存在多种mutex一P存在多种与mutex对应的scoped_lockQ?br />
scoped_lock
scoped_try_lock
scoped_timed_lock
q里我们只讨论scoped_lock?br />
scoped_lock是定义在namespace boost::detail::thread下的Qؓ(f)了方便我们用(也ؓ(f)了方便设计者)Qmutex使用了下面的typedefQ?font color="#990000">
typedef detail::thread::scoped_lock<mutex> scoped_lock;
q样我们可以通过Q?br />
boost::mutex::scoped_lock
来用scoped_lockcL板了?br />
׃scoped_lock的作用仅在于对mutex加锁/解锁Q即使mutex EnterCriticalSection/LeaveCriticalSectionQ,因此Q它的接口也很简单,除了构造函数外Q仅有lock/unlock/lockedQ判断是否已加锁Q,?qing)类型{换操作符void*Q一般我们不需要显式调用这些方法,因ؓ(f)scoped_lock的构造函数是q样定义的:(x)
1 explicit scoped_lock(Mutex& mx, bool initially_locked=true)
2 : m_mutex(mx), m_locked(false)
3 {
4 if (initially_locked) lock();
5 }
注:(x)m_mutex是一个mutex的引用?br />
因此Q当我们不指定initially_locked参数构造一个scoped_lock对象
Ӟscoped_lock?x)自动对所l定的mutex加锁Q而析构函C(x)查是否加锁,若已加锁Q则解锁Q当Ӟ有些情况下,我们可能不需要构造时自动
加锁Q这样就需要自p用lockҎ(gu)。后面的condition、barrier也会(x)调用scoped_lock的lock、unlockҎ(gu)来实现部
分方法?br />
正因为scoped_lockh可在构造时加锁Q析构时解锁的特性,我们l常?x)用局部变量来实现对mutex的独占访问?br />
1 #include <boost/thread/thread.hpp>
2 #include <boost/thread/mutex.hpp>
3 #include <iostream>
4
5 boost::mutex io_mutex;
6
7 void count() // worker function
8 {
9 for (int i = 0; i < 10; ++i)
10 {
11 boost::mutex::scoped_lock lock(io_mutex);
12 std::cout << i << std::endl;
13 }
14 }
15
16 int main(int argc, char* argv[])
17 {
18 boost::thread thrd1(&count);
19 boost::thread thrd2(&count);
20 thrd1.join();
21 thrd2.join();
22
23 return 0;
24 }
在每ơ输Z息时Qؓ(f)了防止整个输E被其它U程打ؕQ通过对io_mutex加锁Q进入(f)界区Q,从而保证了输出的正性?br />
在?
scoped_lockӞ我们有时候需要用全局锁(定义一个全局mutexQ当需要独占访问全局资源Ӟ以该全局mutex为参数构造一?
scoped_lock对象卛_。全局mutex可以是全局变量Q也可以是类的静态方法等Q,有时候则需要用对象锁Q将mutex定义成类的成员变
量)Q应该根据需要进行合理选择?br />
Java的synchronized可用于对Ҏ(gu)加锁Q对代码D加锁,对对象加锁,对类加锁Q仍然是对象U?
的)Q这几种加锁方式都可以通过上面讲的对象锁来模拟Q相反,在Java中实现全局锁好像有炚w烦,必须请求封装到cMQ以转换成上面的四种
synchronized形式之一?br />
condition
condition的接口如下:(x)
1 class condition : private boost::noncopyable // Exposition only
2 {
3 public:
4 // construct/copy/destruct
5 condition();
6 ~condition();
7
8 // notification
9 void notify_one();
10 void notify_all();
11
12 // waiting
13 template<typename ScopedLock> void wait(ScopedLock&);
14 template<typename ScopedLock, typename Pred> void wait(ScopedLock&, Pred);
15 template<typename ScopedLock>
16 bool timed_wait(ScopedLock&, const boost::xtime&);
17 template<typename ScopedLock, typename Pred>
18 bool timed_wait(ScopedLock&, Pred);
19 };
其中wait用于{待某个condition的发生,而timed_wait则提供具有超时的wait功能Qnotify_one用于唤醒一个等待该condition发生的线E,notify_all则用于唤醒所有等待该condition发生的线E?br />
׃condition的语义相对较为复杂,它的实现也是整个boost::thread库中最复杂的(对Windows版本而言Q对支持pthread的版本而言Q由于pthread已经提供了pthread_cond_tQ得condition实现h也十分简单)Q下面对wait和notify_oneq行要分析?br />
condition内部包含了一个condition_impl对象Q由该对象执行来处理实际的wait、notify_one...{操作?br />

]]>