關於訊號量的學習和理解

2021-06-21 12:29:24 字數 1784 閱讀 9926

在下面這篇博文中學習了race condition,

也即如果是要被多個thread共享的共享資源,那麼必須要有訊號量來保護共享資源,

以免多個thread同時訪問導致的程式出錯。

至於是使用互斥鎖還是讀寫鎖還是什麼鎖,根據需要而定即可。

但是鎖用多了就有可能發生死鎖。

所謂死鎖,是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象。

死鎖的四個必要條件是:

1. 互斥條件,在一段時間內某資源只能由乙個程序占用;

如果此時有其它程序請求資源則請求者只能等待直到資源被釋放;

2. 請求和保持條件,指程序已經保持至少乙個資源,而此時又提出了新的資源請求,而該資源此時被其它程序占有;

此時請求程序阻塞,但又對已經獲得的資源保持不放;

3. 不剝奪條件,指程序已獲得的資源,在使用完之前不能被剝奪,只能在使用完時自己釋放;

4. 環路等待條件,指在死鎖發生時,必然存在乙個程序--資源的環形鏈。

死鎖的典型案例是:

程序p1,p2;

不可剝奪資源r1,r2;

p1獲得了r1;

p2獲得了r2;

p1請求r2;

p2請求r1;

預防死鎖的方法是通過設定限制條件,去破壞產生死鎖的四個必要條件中的乙個或幾個,來預防死鎖的發生。

常見的方法有:

1. 有序資源分配法,對系統中的資源按序分配;

2. 設定乙個保持資源的時間,不要一直保持;

對於user space的應用來講,kernel提供的lock/unlock函式必須是"原子操作",

即有了kernel的支援,使得lock/unlock操作不會被中斷。

所謂臨界區,是一次僅允許乙個程序使用的共享資源;

每個程序中訪問臨界資源的那段**稱之為臨界區(critical section);

無論是硬體臨界資源,還是軟體臨界資源,多個程序必須互斥的對它進行訪問。

以下操作是危險的:

res get_shared_resouce(void)

p1: get_shared_resouce---------------------set p to null;

p2:                    get_shared_resouce------------------copy sth to p;

這個動作很危險,系統會因此crash掉。

這裡p是共享資源,對p的讀寫分別使用了mutex進行了保護,可是這樣並不安全。

必須要對讀寫這整個操作保護起來,才不會有問題。

以上講的mutex訊號量可用於共享資源之間的互斥訪問,如果要實現多執行緒之間的同步該怎麼辦呢?

這時候就需要二進位制訊號量了。

二進位制訊號量實現同步的方法是:乙個執行緒先占用訊號量,等待另乙個執行緒來釋放。

假設兩個執行緒t1,t2;

t1 init_func()需要呼叫t2提供的乙個函式init_sth(),而這個init_sth()內部會切換執行緒到t2;

t1必須等到init_sth做完才能繼續下去。

所以,t2 lock;

t1 init_sth;

t1 lock;

待init_sth完成後t2 unlock;

t1繼續執行;

還有一種情況就是:

t1 lock;

t1 init_sth;

t1 lock;//此時t1只能等待直到被其它thread unlock了;

t2 unlock;

t1繼續執行;

使用二進位制訊號量可以方便的實現多個執行緒之間的同步操作。

關於訊號量的理解

參考文件 訊號量的工作原理 由於訊號量只能進行兩種操作等待和傳送訊號,即p sv 和v sv 他們的行為是這樣的 p sv 如果sv的值大於零,就給它減1 如果它的值為零,就掛起該程序的執行 v sv 如果有其他程序因等待sv而被掛起,就讓它恢復執行,如果沒有程序因等待sv而掛起,就給它加1.舉個例...

訊號量的理解

什麼是semaphore 訊號量 訊號量 semaphore 是在多執行緒環境下使用的一種設施,它負責協調各個執行緒,以保證它們能夠正確 合理的使用公共資源。舉例 我們來看看乙個停車場是怎樣運作的。為了簡單起見,假設停車場只有三個車位,一開始三個車位都是空的。這是如果同時來了五輛車,看門人允許其中三...

關於訊號量

1 訊號量的定義 struct semaphore 在linux中,訊號量用上述結構體表示,我們可以通過該結構體定義乙個訊號量。2 訊號量的初始化 可用void sema init struct semaphore sem,int val 直接建立,其中val為訊號量初值。也可以用兩個巨集來定義和初...