//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;
-
}
-
-
- <code class="language-cpp">#include <boost/thread/with_lock_guard.hpp></code>
#include <boost/thread/with_lock_guard.hpp>
-
#bind()封装用
-
//with_lock_guard
-
mutex 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;
-
}