boost mutex lock 使用

来源:互联网 发布:淘宝 买飞机 编辑:程序博客网 时间:2024/05/19 05:39

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<boost::shared_mutex> ReadLock;       typdef boost::shared_lock<boost::shared_mutex> 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<boost::mutex> 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<typename Mutex>      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<boost::mutex> lock(g_mutex);      //do something...  }  void test3()  {      boost::lock_guard<boost::mutex> 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<boost::recursive_mutex > lock(g_mutex);      //do something...  }  void test3()  {  boost::recursive_mutex::scoped_lock<boost::recursive_mutex > lock(g_mutex);       test4();       //do something...  }  int _tmain(int argc, _TCHAR* argv[])  {       test3();       return 0;  }