boost中的mutex貌似有6种或者更多,我用过的有3中boost::mutex、boost::shared_mutex、boost::recursive_mutex,貌似还有boost::try_mutex、boost::time_mutex,不过没用过。
boost::mutex是最基础的锁,有lock和unlock方法,可以认为是互持锁。boost::shared_mutex是共享锁,有lock、unlock方法以及shared_lock、shared_unlock方法。boost::recursive_mutex是重入锁或者称为递归锁,这个最后再说。
boost::shared_mutex可以用来实现读写锁。多线程中的一个经典问题是一写多读,即当有线程发生写操作时,所有其他线程的读操作暂停,其他时刻,允许多个线程同时读操作。使用boost::shared_mutex构造读写锁时需要使用到boost中的lock帮助类系列(作用类似上面我写的mymutexlockguard)。boost::shared_lock和boost::unique_lock,从字面上看,shared_lock是共享的,unique_lock是独占的,shared_lock只允许t是shared_mutex,而unique_lock对t没有限制,如果t是shared_mutex,则在执行加锁和解锁时会调用shared_lock和shared_unlock方法,否则,则执行一般的lock和unlock方法。
实现读写锁:
typedef boost::unique_lock readlock;
typdef boost::shared_lock writelock;
boost::shared_mutex read_write_mutex;
void _readthreadfunc()
{
readlock read_lock(read_write_mutex);
//read data...
}
void _writethreadfunc()
{
writelock write_lock(read_write_mutex);
//write data...
}
使用boost::unique_lock和boost::mutex则可以实现最基本的独占时互斥
boost::unique mylock
boost::mutex mymutex;
void func()
{
mylock lock(mymutex);
// do something...
}
*注意:boost::mutex::scoped_lock和boost::unique是一个东东哦…
还有个东西叫boost::lock_guard,它是比boost::unique更轻量级的lock。看下boost::lock_guard的源代码:
template
class lock_guard
{
private:
mutex& m;
explicit lock_guard(lock_guard&);
lock_guard& operator=(lock_guard&);
public:
explicit lock_guard(mutex& m_):
m(m_)
{
m.lock();
}
lock_guard(mutex& m_,adopt_lock_t):
m(m_)
{}
~lock_guard()
{
m.unlock();
}
};
可以看到只有两个public方法,即构造和析构函数,也就是说,使用boost::lock_guard去guard一个mutex,必然是在boost::lock_guard的对象离开其作用域时unlock它所guard的mutex,不提供提前unlock的功能。
而boost::unique_lock则提供这个功能,除了像boost::lock_guard一样在离开作用域时unlock它guard的mutex外,boost::unique还提供unlock函数,使用者可以手动执行unlock。此外,unique_lock还可以设置超时。
最后说下boost::recursive_mutex,先看下面的逻辑:main调用test3,test3中锁住g_mutex,调用test4,test4中尝试获得g_mutex,结果这个程序将死锁。因为test3锁住g_mutex后,在同一线程(更准确是同一堆栈中)再次尝试获得g_mutex,由于前面的锁未释放,这里将等待,形成死锁。
boost::mutex g_mutex;
void test4()
{
boost::lock_guard lock(g_mutex);
//do something...
}
void test3()
{
boost::lock_guard lock(g_mutex);
test4();
//do something...
}
int _tmain(int argc, _tchar* argv[])
{
test3();
return 0;
}
第二个例子:
void * thread_func_one(void *arg)
{
int i;
for(i=0;i<10;i ){
pthread_mutex_lock( &mutex1);
pthread_mutex_lock( &mutex1);//锁两次
count ;
sleep(1);
pthread_mutex_unlock(&mutex1);
pthread_mutex_unlock(&mutex1);
printf("thread one count value is %d/n",count);
}
return null;
}
同样的道理,也死锁。那么对于这种在一个线程中可能在锁中需要再次获得锁的情况,就需要使用重入锁,boost::recursive_mutex。如下使用就没问题了。
boost::recursive_mutex g_mutex;
void test4()
{
boost::recursive_mutex::scoped_lock lock(g_mutex);
//do something...
}
void test3()
{
boost::recursive_mutex::scoped_lock lock(g_mutex);
test4();
//do something...
}
int _tmain(int argc, _tchar* argv[])
{
test3();
return 0;
}