程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UNIX網絡編程-鎖(二)

UNIX網絡編程-鎖(二)

編輯:C++入門知識

Table of Contents

  • 1 UNIX網絡編程-鎖(二)
    • 1.1 信號量API
    • 1.2 信號量互斥鎖的實現
      • 1.2.1 成員變量如下:
      • 1.2.2 實現的成員函數如下:
    • 1.3 信號量讀寫鎖的實現
      • 1.3.1 RWSem的成員變量:
      • 1.3.2 RWSem的成員函數:
    • 1.4 信號量讀寫實現源碼下載

此博客是關於一篇信號量的文章,信號量提供進程間互斥,很方便。用mutex來實現信號量的功能,必須將mutex建立在共享內存上才能實現。所以當需要線程間互斥的時候,最好是用mutex;當用進程間互斥的時候,用sem。歸結起來,mutex直接用到進程上,顯得無用; sem用到線程上,顯得畫蛇添足。

1.1 信號量API

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當前值;否則就獲取值出錯了

1.2 信號量互斥鎖的實現

信號量的互斥鎖的類為SemMutex。

1.2.1 成員變量如下:

Sem mutex_; Sem實際上封裝了一個sem*指針,初始化為SEM_FAILED

std::string name_; 信號量的名稱

1.2.2 實現的成員函數如下:

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的時候是加鎖狀態,就會阻塞。

1.3 信號量讀寫鎖的實現

信號量讀寫鎖的實現,需要一個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

1.3.1 RWSem的成員變量:

SemMutex* p_mutex_; 實現讀寫互斥

Sem* p_read_; 記錄當前正在讀鎖的個數

1.3.2 RWSem的成員函數:

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-讀鎖

1.4 信號量讀寫實現源碼下載

rw_mutex為信號量互斥鎖的實現以及rw_sem為信號量讀寫鎖的實現

信號量互斥鎖的例子

信號量讀寫鎖的例子

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved