poco Mutex(互斥量)
来源:互联网 发布:如何修改网卡mac地址 编辑:程序博客网 时间:2024/06/07 20:35
作用:
互斥量用于线程间同步。实际上就是锁住某部分指令。
linux 底层的 api 互斥量使用还是很麻烦的。pthread_mutex_init()
pthread_mutex_lock() pthread_mutex_destory()
下面是 Poco 里关于锁的一些实现。
要看 Poco::Mutex 所以我们应该去看基类 Poco::MutexImpl 类的实现。
class Foundation_API MutexImpl{protected: MutexImpl(); MutexImpl(bool fast); ~MutexImpl(); void lockImpl(); bool tryLockImpl(); bool tryLockImpl(long milliseconds); void unlockImpl();private: pthread_mutex_t _mutex;};
MutexImpl () 默认构造函数主要是执行锁的初始化,初始化为可以递归的锁。即同一个线程可以多次进行锁。
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&_mutex, &attr); pthread_mutexattr_destroy(&attr);
MutexImpl( bool fast ) 带参数构造函数 主要在设置递归锁的时候判断标志位 fast.如果 fast 为true 那么为不可递归的互斥量。也就是下面将要讲到的 Poco::FastMutex ,如果为 false 那么就是可以递归的互斥量也就是 Poco::Mutex。
pthread_mutexattr_settype(&attr, fast ? PTHREAD_MUTEX_NORMAL : PTHREAD_MUTEX_RECURSIVE);
主要的方法:
void lockImpl();//加锁 bool tryLockImpl();//调用tryLock 函数。成功返回 true,失败返回 false. bool tryLockImpl(long milliseconds);//调用pthread_mutex_timeLock() 函数。成功返回 true,失败返回 false. void unlockImpl();//解锁。
Poco::Mutex 私有继承 MutexImpl
class Foundation_API Mutex: private MutexImpl
Poco::Mutex 创建的是默认的可以递归的互斥量(需要注意的是同一线成可以多次锁,但是要多次解锁,不同线程不行)。
void lock(); void lock(long milliseconds); bool tryLock(); bool tryLock(long milliseconds);//等待获取锁,到达时间没有获取返回 false。 void unlock();
Poco 最简单的互斥量使用,两个线程,每个线程都先获取锁 2S 之后释放锁。
#include <iostream>#include <Poco/Mutex.h>#include <Poco/Thread.h>#include <unistd.h>class Worker : public Poco::Runnable{public: Worker( Poco::Mutex& mtx ): _mtx(mtx) { } void run( ) { //获取锁 _mtx.lock(); std::cout << Poco::Thread::currentTid() << " get mtx" << std::endl; sleep( 2 ); _mtx.unlock(); }private: Poco::Mutex& _mtx;};int main( ){ Poco::Mutex mtx; Poco::Thread th1,th2; Worker w1( mtx ); Worker w2( mtx ); th1.start( w1 ); th2.start( w2 ); th1.join(); th2.join();}
可以一个线程先获取了锁,等了两秒之后先获取锁的线程释放了锁,第二个线程才能获取锁。
Poco::FastMutex 继承于 FastMutexImpl
FastMutexImpl 继承于 Poco::MutexImpl
FastMutexImpl 的构造函数指定调用 MutexImpl( true ) 够造一个不能多次锁的普通锁对象。
所以 FastMutex 的功能和 Mutex 的功能一样只是,不能多次锁,否则造成死锁。
在 Poco 互斥量里有一个不得不说的类它就是 Poco::ScopedLock。是一个模板类。它只有3 个 public 方法。
两个构造函数,第一个ScopedLock(M& mutex)是调用传进来的 互斥量的 lock() 方法。第二个ScopedLock(M& mutex, long milliseconds) 是调用传捡来的互斥量的 lock( milliseconds ) 方法。
一个析构函数调用 互斥量的 unlock() 方法。所以使用 Poco::ScopeLock 类的作用是在构造的时候会自动获取锁,在函数退出的时候自动释放锁。
ScopeLock 在Mutex 和 FastMutex 都有实例化。所以使用的锁如果是
Mutex 类型的那么只要
Poco::Mutex::ScopedLock s( _mtx );
Poco::FastMutex::ScopeLock( _mtx );
template <class M>class ScopedLock{public: explicit ScopedLock(M& mutex): _mutex(mutex) { _mutex.lock(); } ScopedLock(M& mutex, long milliseconds): _mutex(mutex) { _mutex.lock(milliseconds); } ~ScopedLock() { try { _mutex.unlock(); } catch (...) { poco_unexpected(); } }
下面还是刚刚那个例子。现在改成使用 ScopeLock 来实现。
#include <iostream>#include <Poco/Mutex.h>#include <Poco/Thread.h>#include <unistd.h>class Worker : public Poco::Runnable{public: Worker( Poco::Mutex& mtx ): _mtx(mtx) { } void run( ) { //获取锁 Poco::Mutex::ScopedLock s( _mtx ); std::cout << Poco::Thread::currentTid() << " get mtx" << std::endl; sleep( 2 ); }private: Poco::Mutex& _mtx;};int main( ){ Poco::Mutex mtx; Poco::Thread th1,th2; Worker w1( mtx ); Worker w2( mtx ); th1.start( w1 ); th2.start( w2 ); th1.join(); th2.join();}
从上面代码可以看出来。使用 ScopeLock 可以不需要关心释放锁。所以推荐使用 ScopeLock.
既然有 ScopeLock() 类可以自动帮我我获取锁,退出函数帮我们释放锁。那么有没有哪个类,可以帮我们在自动释放锁,退出函数的时候自动加锁。ScopedUnlock 类就可以实现这样的功能。
应用场景:
比如说当一个线程(A)获取了锁需要从数据库链接池获取一个数据链接,但是此时没有,那么并且需要等到另外的线程(B,C,D)的释放链接信号才能继续执行。但线程B 把链接放回池需要获取锁,这个时候那应该就是 线程 A 在进入阻塞等待之前先释放锁,然后 B 获取了锁,把链接放回去,才发送信号。A 接收到信号之后,激活继续向下 运行,在退出函数的时候重新获取锁。
例子先不写了。下一篇的 Poco::Event 线程间通信可在细述。
转载请注明出处
http://blog.csdn.net/yuhaiyang457288/
- poco Mutex(互斥量)
- Poco::Mutex
- c++ poco Mutex相关 源码剖析
- 互斥量Mutex
- 互斥量Mutex
- Mutex(互斥量)
- Mutex 互斥量
- 互斥量mutex
- POCO
- 多线程--同步(Mutex互斥量)
- 互斥量(mutex)
- 线程-互斥量mutex
- 多线程之互斥量mutex
- 多线程之Mutex(互斥量)
- 【多线程】(七)互斥量Mutex
- 互斥量的同步(Mutex)
- 线程同步---互斥量mutex
- 线程同步--互斥量Mutex
- Java BitSet
- 社説 20150710 中国株乱高下 強引な市場介入が招いた混迷
- python操作日期和时间的方法
- 代码控制ImageView的src属性
- android caculator
- poco Mutex(互斥量)
- Hadoop之hive学习命令
- 在iOS中创建静态库
- Python下opencv使用笔记(五)(图像的平滑与滤波)
- Change the port number in WAS 8.5
- noip2014
- Unity3D–Texture图片空间和内存占用分析
- Swift教程之循环语句
- 社説 20150710 参院選制度改革 「合区」の導入もやむを得ない