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...