標籤:sse 操作 作用 nbsp 友元 對象管理 錯誤 模式 exp
1.互斥鎖簡介
互斥鎖主要用於互斥,互斥是一種競爭關係,用來保護臨界資源一次只被一個線程訪問。
POSIX Pthread提供下面函數用來操作互斥鎖。
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);int pthread_mutex_destroy(pthread_mutex_t *mutex);//返回://pthread_mutex_init總是返回0//其他mutex函數返回0表示成功,非0的錯誤碼錶示失敗
#define CHECK(exp) if(!exp) { fprintf(stderr, "File:%s, Line:%d Exp:[" #exp "] is true, abort.\n",__FILE__, __LINE__); abort(); }
由於pthread系列函數返回成功的時候都是0,因此,我們可以寫一個宏作為一個輕量級的檢查手段,來判斷處理錯誤。
實際使用的時候只需: CHECK(!pthread_mutex_lock(&mutex));
2.互斥鎖的封裝
需要考慮以下幾個問題:
a.互斥鎖的初始化與銷毀。
b.互斥鎖的操作:加鎖和釋放鎖。
另外,我們的自己封裝的類不應該有賦值和拷貝構造的語義,這一點跟單例模式類似,我們可以使我們的類繼承自boost庫的noncopyable。
//MutexLock.h#ifndef __MUTEXLOCK_H__#define __MUTEXLOCK_H__#include <iostream>#include <cstdio>#include <boost/noncopyable.hpp>#include <pthread.h>#include <assert.h>#define CHECK(exp) if(!exp) { fprintf(stderr, "File:%s, Line:%d Exp:[" #exp "] is true, abort.\n",__FILE__, __LINE__); abort();}class MutexLock : public boost::noncopyable{ friend class Condition;//條件變數友元聲明 public: MutexLock(); ~MutexLock(); void lock(); void unlock(); bool isLocking() const { return isLocking_; } pthread_mutex_t *getMutexPtr() { return &mutex_; } private: void restoreMutexStatus() { isLocking_=true; } pthread_mutex_t mutex_;//互斥鎖 bool isLocking_;};#endif
這裡完成了MutexLock 類的聲明,但是這裡還需要一些補充,那就是使用RAII(資源擷取即初始化)技術,對MutexLock初始化和析構進行處理:初始化的時候加鎖,析構的時候解鎖,這就需要我們重新定義一個class MutexLockGuard對MutexLock進行操作
class MutexLockGuard:public boost::noncopyable{ public: MutexLockGuard(MutexLock &mutex):mutex_(mutex){ mutex_.lock();}//構造時加鎖 ~MutexLockGuard()//析構時解鎖 { mutex_.unlock(); } private: MutexLock &mutex_;//注意這裡為什麼是引用!!!!};
下面就要具體實現幾個函數了,主要是:
pthread_mutex_init()、pthread_mutex_destroy()、pthread_mutex_lock()、pthread_mutex_unlock()這四個函數的封裝:
#include "MutexLock.h"MutexLock::MutexLock():isLocking_(false){ CHECK(!pthread_mutex_init(&mutex_,NULL));}MutexLock::~MutexLock(){ assert(!isLocking()); CHECK(!pthread_mutex_destroy(&mutex_));}
void MutexLock::lock(){ CHECK(!pthread_mutex_lock(&mutex_))//先加鎖再修改狀態,保證以下賦值操作的原子性。 isLocking_=true;}void MutexLock::unlock(){ isLocking_=false;//先修改狀態在解鎖,保證賦值操作的原子性。 CHECK(!pthread_mutex_unlock(&mutex_));}
封裝以後,我們使用:
MutexLockGurad lock(mutex);//就是 MutexLock對象被另一個對象管理
對臨界區進行加鎖,而只要我們控制好lock變數的生存期,就能控制臨界區,例如:
int count=0;{ MutexLockGurad lock(mutex); count++;}//臨界區//...//離開lock的範圍,lock作為棧上變數,自動釋放,調用解構函式,同時釋放鎖。
c++ 封裝線程庫 0