Boost Thread中mutex 用法
来源:互联网 发布:汤姆克鲁斯 知乎 编辑:程序博客网 时间:2024/06/10 01:36
除了thread,boost::thread另一个重要组成部分是mutex,以及工作在mutex上的boost::mutex::scoped_lock、condition和barrier,这些都是为实现线程同步提供的。
mutex
boost提供的mutex有6种:
boost::mutex
boost::try_mutex
boost::timed_mutex
boost::recursive_mutex
boost::recursive_try_mutex
boost::recursive_timed_mutex
下面仅对boost::mutex进行分析。
mutex类是一个CriticalSection(临界区)封装类,它在构造函数中新建一个临界区并InitializeCriticalSection,然后用一个成员变量
void* m_mutex;
来保存该临界区结构。
除此之外,mutex还提供了do_lock、do_unlock等方法,这些方法分别调用EnterCriticalSection、 LeaveCriticalSection来修改成员变量m_mutex(CRITICAL_SECTION结构指针)的状态,但这些方法都是private的,以防止我们直接对mutex进行锁操作,所有的锁操作都必须通过mutex的友元类detail::thread::lock_ops<mutex>来完成,比较有意思的是,lock_ops的所有方法:lock、unlock、trylock等都是static的,如lock_ops<Mutex>::lock的实现:
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的设计者为什么会这么设计呢?我想大概是:2 class lock_ops : private noncopyable
3 {
4
5 public:
6 static void lock(Mutex& m)
7 {
8 m.do_lock();
9 }
10
11 }
1、boost::thread的设计者不希望被我们直接操作mutex,改变其状态,所以mutex的所有方法都是private的(除了构造函数,析构函数)。
2、虽然我们可以通过lock_ops来修改mutex的状态,如:
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 }
但是,这是不推荐的,因为mutex、scoped_lock、condition、barrier是一套完整的类系,它们是相互协同工作的,像上面这么操作没有办法与后面的几个类协同工作。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 }
scoped_lock
上面说过,不应该直接用lock_ops来操作mutex对象,那么,应该用什么呢?答案就是scoped_lock。与存在多种mutex一样,存在多种与mutex对应的scoped_lock:
scoped_lock
scoped_try_lock
scoped_timed_lock
这里我们只讨论scoped_lock。
scoped_lock是定义在namespace boost::detail::thread下的,为了方便我们使用(也为了方便设计者),mutex使用了下面的typedef:
typedef detail::thread::scoped_lock<mutex> scoped_lock;
这样我们就可以通过:
boost::mutex::scoped_lock
来使用scoped_lock类模板了。
由于scoped_lock的作用仅在于对mutex加锁/解锁(即使mutex EnterCriticalSection/LeaveCriticalSection),因此,它的接口也很简单,除了构造函数外,仅有lock/unlock/locked(判断是否已加锁),及类型转换操作符void*,一般我们不需要显式调用这些方法,因为scoped_lock的构造函数是这样定义的:
1 explicit scoped_lock(Mutex& mx, bool initially_locked=true)
2 : m_mutex(mx), m_locked(false)
3 {
4 if (initially_locked) lock();
5 }
2 : m_mutex(mx), m_locked(false)
3 {
4 if (initially_locked) lock();
5 }
注:m_mutex是一个mutex的引用。
因此,当我们不指定initially_locked参数构造一个scoped_lock对象时,scoped_lock会自动对所绑定的mutex加锁,而析构函数会检查是否加锁,若已加锁,则解锁;当然,有些情况下,我们可能不需要构造时自动加锁,这样就需要自己调用lock方法。后面的condition、barrier也会调用scoped_lock的lock、unlock方法来实现部分方法。
正因为scoped_lock具有可在构造时加锁,析构时解锁的特性,我们经常会使用局部变量来实现对mutex的独占访问。
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 }
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 }
在每次输出信息时,为了防止整个输出过程被其它线程打乱,通过对io_mutex加锁(进入临界区),从而保证了输出的正确性。
在使用 scoped_lock时,我们有时候需要使用全局锁(定义一个全局mutex,当需要独占访问全局资源时,以该全局mutex为参数构造一个 scoped_lock对象即可。全局mutex可以是全局变量,也可以是类的静态方法等),有时候则需要使用对象锁(将mutex定义成类的成员变量),应该根据需要进行合理选择。
Java的synchronized可用于对方法加锁,对代码段加锁,对对象加锁,对类加锁(仍然是对象级的),这几种加锁方式都可以通过上面讲的对象锁来模拟;相反,在Java中实现全局锁好像有点麻烦,必须将请求封装到类中,以转换成上面的四种 synchronized形式之一。
0 0
- Boost Thread中mutex 用法
- Boost Thread中mutex 用法
- boost::thread mutex
- Boost Thread 临界区 mutex
- 【Boost】boost库中thread多线程详解2——mutex与lock
- 【Boost】boost库中thread多线程详解2——mutex与lock
- C++11 中std::thread和std::mutex的用法
- boost库中thread多线程详解2——mutex与lock
- boost库中thread多线程详解——mutex与lock
- boost库中thread多线程详解——mutex与lock
- boost::thread用法
- boost::thread用法
- Boost::Thread用法
- boost::thread用法
- boost综合使用<function,bind,thread,mutex,condition_variable,shared_ptr>
- boost::thread 的各种用法
- boost mutex
- boost Mutex
- mark 很好用的 事件冲突
- Mysql 日志分析工具介绍
- scroll()实现导航栏跟随滚动
- github创建repository,上传项目,更新项目操作步骤总结
- JAVA进阶-集合(1)
- Boost Thread中mutex 用法
- Boost::Thread使用示例
- Mybatis 中Expected one result (or null) to be returned by selectOne(), but found: 5
- HDFS Federation客户端(viewfs)配置攻略
- linux ping命令实现网络监控 并邮件提醒管理员
- cocos2dx[3.2]小知识——Sprite转换为Image
- 修改手机铃声和通知音
- 企业IT管理员IE11升级指南【1】—— Internet Explorer 11增强保护模式 (EPM) 介绍
- 百度地图实现根据路线添加覆盖物