此博客是關於一篇信號量的文章,信號量提供進程間互斥,很方便。用mutex來實現信號量的功能,必須將mutex建立在共享內存上才能實現。所以當需要線程間互斥的時候,最好是用mutex;當用進程間互斥的時候,用sem。歸結起來,mutex直接用到進程上,顯得無用; sem用到線程上,顯得畫蛇添足。
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
創建一個信號量,value值很重要,初始化信號量的為value。
int sem_unlink(const char *name);
依據名字來銷毀信號量
sem_t *sem_open(const char *name, int oflag);
打開一個已經存在的信號量
int sem_close(sem_t *sem);
關閉一個信號量,並不是銷毀它,依舊存在於內核中,只是從當前進程中卸載。
int sem_wait(sem_t *sem);
sem的值為0,就一直等待;否則就將sem的值-1
int sem_trywait(sem_t *sem);
sem的值為0,就放棄等待,返回值EAGAIN;否則就將sem的值-1
int sem_post(sem_t *sem);
sem的值+1
int sem_getvalue(sem_t *sem, int *
如果返回成功,sval就是sem當前值;否則就獲取值出錯了
信號量的互斥鎖的類為SemMutex。
Sem mutex_; Sem實際上封裝了一個sem*指針,初始化為SEM_FAILED
std::string name_; 信號量的名稱
SemMutex(const char* name);
構造函數初始化Mutex的名稱
bool Create();
調用sem_open, 創建信號量, 重要的是信號量的計數初始化為1
bool Destroy();
銷毀信號量
bool Open();
打開已經創建的信號量
bool IsOpen();
信號量是否已經打開,實際上判斷sem指針是否為SEM_FAILED
bool Lock();
調用sem_wait, 如果信號量的值當前為0,一直等待,表示已經占用了鎖資源; 否則sem的值就-1
bool UnLock();
調用sem_post, 釋放鎖資源,sem的值+1
bool TryLock();
調用sem_trywait, 如果鎖資源已經占用,sem的值為0,就不用等待,直接返回EAGAIN。
int LockStatus();
獲取鎖的狀態, -1 ,錯誤,0 - 加鎖狀態,1 - 無鎖狀態;實際上其調用sem_getvalue來獲取sem的計數,來查看狀態的。 實際上,實現互斥信號量,就是實現一個2值信號量,信號量的值一直在0和1之間變化;1 的時候是無鎖狀態,不會阻塞;0的時候是加鎖狀態,就會阻塞。
信號量讀寫鎖的實現,需要一個Sem來記錄同時正在read的個數,以及一個SemMutex來實現互斥,其類為RWSem。
其關鍵就是鎖狀態的判定了。
p_mutex_->LockStatus == UNLOCK; 表明無鎖
p_mutex_->LockStatus == LOCK && p_read_->GetValue() == 0; 已經加了寫鎖, 即已經加鎖,但是讀鎖的個數為0
p_mutex_->LockStatus == LOCK && p_read_->GetValue() > 0; 已經加了讀鎖, 即已經加鎖,但是讀鎖的個數>0
SemMutex* p_mutex_; 實現讀寫互斥
Sem* p_read_; 記錄當前正在讀鎖的個數
bool Create();
創建p_mutex_和p_read_
bool Destroy();
銷毀p_mutex_和p_read_
bool Open();
打開p_mutex_和p_read_
bool Close();
關閉p_mutex_和p_read_
bool WLock();
嘗試讀鎖,當讀鎖已經占住了資源或者寫鎖站住資源,就會失敗;而不管哪種鎖占用了資源,p_mutex_的LockStatus都是鎖住狀態。 實現機制就是調用p_mutex_的Wait就OK了
bool TryWLock();
嘗試讀鎖,當讀鎖已經占住了資源或者寫鎖站住資源,就會失敗;而不管哪種鎖占用了資源,p_mutex_的LockStatus都是鎖住狀態。 實現機制就是調用p_mutex_的TryWait就OK了
bool TryRLock();
當寫鎖占住資源的時候,返回false
當寫鎖沒占住資源並且讀鎖也沒占住資源的時候, p_read_調用Post,讀鎖的個數+1, 並且調用p_mutex_->Wait(),
當寫鎖沒占住資源並且讀鎖已經占住資源的時候, p_read_調用Post, 讀鎖的個數+1, 不用調用p_mutex_->Wait(),否則會阻塞掉的。
bool RLock();
當寫鎖占住資源的時候,調用p_mutex_->Wait(), 讓其阻塞
當寫鎖沒占住資源並且讀鎖也沒占住資源的時候, p_read_調用Post,讀鎖的個數+1, 並且調用p_mutex_->Wait(), 表示這個鎖資源已經被占用
當寫鎖沒占住資源並且讀鎖已經占住資源的時候, p_read_調用Post, 讀鎖的個數+1, 不用調用p_mutex_->Wait(),否則會阻塞掉的。
bool UnLock();
當加的鎖為讀鎖的時候,調用p_read_.Post(), 讀鎖的個數-1,如果讀鎖的個數減到0,就調用p_mutex_->Post(), 解除鎖資源的占用
當加的是寫鎖的時候, 調用p_mutex_.Post(),
int LockStatus();
0 - 無鎖;1- 寫鎖;2-讀鎖
rw_mutex為信號量互斥鎖的實現以及rw_sem為信號量讀寫鎖的實現
信號量互斥鎖的例子
信號量讀寫鎖的例子