C++多线程-第二篇-Mutex(互斥量)
来源:互联网 发布:棋牌全套源码 编辑:程序博客网 时间:2024/06/15 22:44
//Boost
#include<boost/thread/thread.hpp>
#define BOOST_THREAD_VERSION 4 //使用最新版本,含有1,2,3但只是为了兼容之前程序。
Thread库丰富强大的扩展功能但不在Thread中的未看。
//C++11
#include <mutex>
using namspace std;
Mutex(互斥量)
1.Mutex类
基本作用: 互斥占有一个变量,一段时间内仅一个线程可以访问。
即该类可以限制对某物的访问,只有先获得许可才可访问某物,否则一般可设为阻塞等待。
互斥量*6
mull_mutex
无任何锁定功能的“互斥量”,空对象模式是用。
mutex
独占式互斥量,最简单但最常用
timed_mutex
独占式互斥量,一段时间内试图锁定,若超时则返回false
recursive_mutex
递归式互斥量,可以多次锁定,相应的也要多次解锁
Recursive_timed_mutex
递归式互斥量,同样增加一段时间内试图锁定,若超时则返回false
Shared_mutex
多读者,单写者的共享互斥量(读写锁)
一般成员函数:
Class Mutex
{
Public:
Void lock(); //锁定,否则阻塞
Void unlock(); // 解锁
Bool try_lock(); //尝试锁定,但不会阻塞
Bool try_lock_for(const duration &rel_time); //timed_ 特有,阻塞一段时间后尝试锁定
Bool try_lock_until(const time_point &t);// timed_ 特有,阻塞一段时间后尝试锁定
others...
};
Code:
mutex mutex_thread_1;try{mutex_thread_1.lock();cout << "Do Something" << endl;mutex_thread_1.unlock();}catch (std::exception e){//cout << << endl;;mutex_thread_1.unlock();}timed_mutex t_mutex_1;auto flag = t_mutex_1.try_lock_for(boost::chrono::milliseconds(100));if (flag){cout << "访问共享" << endl;t_mutex_1.unlock();}else{cout << "未获得锁,进行其他操作" << endl;}
2.Lock_guard()-- Mute的优秀辅助
作用:此类辅助锁定互斥量,构造时锁定,析构时解锁,避免遗忘解锁,也就是说在其作用域内他会一直锁定要求的变量。
类似智能指针?
附加扩展:with_lock_guard()借助lock_guard()在函数中互斥使用某锁定资源,(封装函数用?)
mutex mu;lock_guard<mutex> g(mu);//作用域内自动智能加锁/解锁cout << "Do something" << endl;timed_mutex t_mu;if (mu.try_lock_for(boost::chrono::microseconds(100))){lock_guard<timed_mutex> g(t_mu,adopt_lock);//不会再次加锁cout << "Do something" << endl;}
#include <boost/thread/with_lock_guard.hpp>
#bind()封装用//with_lock_guardmutex fmu;string name = "ZGJ";int rul = with_lock_guard(fmu, bind(Alloa,argv1,argv2...));//添加参数需谨慎,为Boost中参数类型,Alloa为函数,argv为其参数cout << rul << endl;With_lock_guard(lockable& m, Function && fun, Args &&...args) 类似于{Lock_guard<lockable> g(m);Return func(argc...)}
3. unique_lock()--升级的lock_guard()
该类有很丰富的选项,但不可复制。例如:锁定选项---占有但不锁定
如构造函数有
unique_lock(Lockable & mu) ;//锁定
unique_lock(Lockable & mu,boost::adopt_lock_t);//不锁定,但会解锁
unique_lock(Lockable & mu,boost::defer_lock_t);//不锁定互斥量
unique_lock(Lockable & mu,boost::try_to_lock_t);//尝试锁定互斥量
unique_lock(Lockable & mu,const time_point &t);//超时锁定
make_unique_lock(Lockable &mu,option);
//基于unique_lock(),利用函数重载帮助我们不用输入互斥量类型,其实就是类似于
templat<class T_>
unique_lock<lockable> my_make_unique_lock(lockable& mu, T_ my_x)
{
return unique_lock<lockable>(mux,my_x);
}
Code:
#include<boost\thread\lock_factories.hpp>mutex m_un_lock;
{//此类大括号活用作用域,供make_unique_lock析构使用。auto g = make_unique_lock(m_un_lock);//工厂函数锁定互斥量assert(g.owns_lock());//断言 -- 已经锁定cout << "Do something" << endl;}{auto g = make_unique_lock(m_un_lock, defer_lock);//暂不锁定互斥量assert(!g);// 断言 -- 没有锁定assert(g.try_lock());//尝试锁定assert(g);//断言 -- 已经锁定cout << "Do something" << endl;}timed_mutex t_mu_un;{auto g = unique_lock<timed_mutex>(t_mu_un, boost::chrono::milliseconds(100)); //限时100MS尝试锁定if (g){cout << "Lock timed mutex" << endl;}}auto g = make_unique_locks(t_mu_un, m_un_lock);//同时锁定多个互斥量assert(std::tuple_size<decltype(g)>::value == 2);//测试是否锁定2个
4.Lock适配器/Lock概念检查/lock函数
4.1Lock适配器
Lock_guard 与 unique_lock是模板类所以只要是满足<LockAble>(含有lock/unlock/try_lock)
的接口的类都可以使用它,实现原子操作等。
Lockable适配器类就是为了方便我们实现Lockable的。
Basic_lockable_adapter
最简单接口,提供lock与unlock
Lockable_adapter
基本接口,增加try_lock
Timed_lockable_adapter
增加try_lock_for/try_lock_until
Code:
#include<iostream>#include<boost/thread/thread.hpp>#include<boost/atomic.hpp>//原子库#include<boost/thread/lockable_adapter.hpp> //Lockable 适配器#include<boost/thread/lock_factories.hpp>using namespace std;using namespace boost;class account : public lockable_adapter<mutex>{private:atomic<int> m_money_{ 0 }; //账户金额public:account(){}~account(){}int sum()const{return m_money_;}void withdraw(int x){m_money_ -= x;}void deposit(int x)//存钱{m_money_ += x;}void show(){cout << m_money_ << endl;}};int main(){account a;{auto g = make_unique_lock(a);a.deposit(100);a.show();a.withdraw(20);a.show();assert(a.sum() == 80);}{auto b = make_unique_lock(a, try_to_lock);if (b){a.withdraw(a.sum());assert(a.sum() == 0);a.show();}}return 0;}
4.2.Lock概念检查
概念检查类保证我们在泛型编程时确保使用的模板参数满足Lockable该每年,在编译时保证程序的正确性。
4.3.Lock函数
Lock() / try_lock()操作mutex类似make_unique_locks() 可以一起锁定多个Mutex,而且保证不会死锁。他们不具有退出作用域自动解锁,但他们在自身异常时会解除锁定
所以一般配合unique_lock的adopt_lock或者defer_lock锁定选项,但暂时不锁定互斥量.
Code:
mutex m1, m2;{auto g1 = make_unique_lock(m1, adopt_lock);auto g2 = make_unique_lock(m2, adopt_lock);lock(m1, m2);}//unique_lock自动解锁{auto g1 = make_unique_lock(m1, defer_lock);auto g2 = make_unique_lock(m2, defer_lock);try_lock(g1, g2);} //unique_lock自动解锁
5.补:Shared_mutex.
一个特权--写,多个普权--读
Code:
#include<iostream>#include<boost/thread/thread.hpp>#include<boost/chrono.hpp>#include<boost/bind.hpp>#include<boost/ref.hpp>using namespace std;using namespace boost;class rw_data{private:int m_x;shared_mutex rw_mu;public:rw_data() :m_x(0){}void write(){unique_lock<shared_mutex> g(rw_mu);++m_x;}void read(int &x){shared_lock<shared_mutex> g(rw_mu);x = m_x;}};mutex xzz;void writer(rw_data &d){for (int i = 0; i < 2; ++i){this_thread::sleep_for(chrono::microseconds(3000));d.write();}}void reader(rw_data &d){int x;for (int i = 0; i < 10; i++){this_thread::sleep_for(chrono::microseconds(5000));d.read(x);xzz.lock();cout << this_thread::get_id() << "reader:" << x << endl;xzz.unlock();}}int main(){//读写锁机制rw_data d;thread_group pool;pool.create_thread(bind(writer, boost::ref(d)));pool.create_thread(bind(writer, boost::ref(d)));pool.create_thread(bind(reader, boost::ref(d)));pool.create_thread(bind(reader, boost::ref(d)));pool.create_thread(bind(reader, boost::ref(d)));pool.create_thread(bind(reader, boost::ref(d)));pool.join_all();std::system("pause");return 0;}
- C++多线程-第二篇-Mutex(互斥量)
- 多线程第五篇:互斥量Mutex
- 多线程(C++)同步Mutex
- 多线程(C++)同步Mutex
- 多线程--同步(Mutex互斥量)
- 多线程之互斥量mutex
- 多线程之Mutex(互斥量)
- 【多线程】(七)互斥量Mutex
- 多线程-互斥量Mutex
- 多线程互斥量Mutex的使用
- 多线程基础篇2-------<mutex>
- 秒杀多线程第七篇 经典线程同步 互斥量Mutex
- 秒杀多线程第七篇 经典线程同步 互斥量Mutex
- 秒杀多线程第六篇 经典线程同步 互斥量Mutex
- 秒杀多线程第七篇 经典线程同步 互斥量Mutex
- 秒杀多线程第七篇 经典线程同步 互斥量Mutex
- 秒杀多线程第七篇 经典线程同步 互斥量Mutex
- 秒杀多线程第七篇 经典线程同步 互斥量Mutex
- 从子页面跳回父页面,保持父页面信息
- android 设定wifi SSID和MAC地址的绑定
- libevent 2.0.16-stable移植到android记录 附源码
- 树上随机游走的期望距离
- boost shared_ptr的使用方法
- C++多线程-第二篇-Mutex(互斥量)
- 解决windows 7 旗舰版 不是aero样式的问题
- 栈帧详解
- java用url获取网页内容并输出到控制台
- 百度云资源搜索
- 滑块移动
- 2016.12.23最新的CocoaPods安装教程
- 你真的了解cookie吗??
- PHP 静态变量