UNIX網路程式設計 鎖(二)

2022-04-02 10:23:04 字數 3237 閱讀 3409

1.3 訊號量讀寫鎖的實現

此部落格是關於一篇訊號量的文章,訊號量提供程序間互斥,很方便。用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。

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

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

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

訊號量互斥鎖的例子

訊號量讀寫鎖的例子

unix網路程式設計 鎖(一)

閱讀了unix網路程式設計的卷二之後,看著裡面的例項並且理解其原理演算法,就將裡面的c語言的鎖api進行c 封裝以供以後使用。實現的鎖介面以及一些演算法會封裝到我的timepass庫中。我覺得應該就鎖的問題寫乙個系列的部落格。鎖按照其作用域可以分為執行緒鎖和程序鎖 按照其工作方式 又可以分為互斥鎖,...

UNIX網路程式設計(二)

udp不保證udp資料報會到達其最終目的地,不保證各個資料報的先後順序跨越網路後保持不變,也不保證每個資料報只到達一次。tcp提供客戶與伺服器之間的連線,還提供了可靠性。建立乙個tcp連線會發生三次握手 伺服器必須準備好接受外來的連線。這通常通過socket bind listen這三個函式來完成。...

同步鎖 摘自《unix網路程式設計》第二卷

書中還提到 即使乙個程序終止時系統自動釋放某個鎖,那也可能解決不了問題。該鎖保護某個臨界區很可能是為了在執行該臨界區 期間更新某個資料。如果該程序在執行該臨界區的中途終止,該資料處於什麼狀態呢?該資料處於不一致狀態的可能性很大。如果核心僅僅在程序終止時自動解鎖的話,通常於事無補。需要小心使用。關於p...