併發:互斥與訊號量
一、關鍵術語
1原子操作:乙個或多個指令的序列,對外是不可分的;即沒有其他程序可以看到其中間狀態或者中斷此操作。
2.臨界區(critical section):是一段**,在這段**中程序將訪問資源;只能有乙個程序在此段**中執行。
3.互斥(mutual exclusion):當乙個程序在臨界區訪問共享資源時,其他程序不能進入臨界區訪問任何資源。
二、互斥
1.為什麼要互斥:因為當多個程序同時執行在臨界區對共享資源進行操作時,可能會導致得到非預期結果。
2.互斥的實現
2.1硬體方法
2.1.1 中斷禁用
在單處理器機器中,併發程序只能序列執行,所以只要禁止對臨界區的中斷即可保證互斥。
缺點:導致效率降低;不能用於多處理器機器。
2.1.2 專用機器指令
設計專門的指令,保證指令執行是原子的。
1).比較和交換指令
intcompare_and_swap(int &word, int testval, int newval)
intoldval=word;
if(old==testval)word=newval;
returnoldval;
compare_and_swap是機器指令,在執行期間不會被中斷。
while(compare_and_swap(a,0,1)==1); //初始化a=0
//臨界區
a=0;
第乙個程序執行時,a=0,指令返回0,所以程序進入臨界區,然後a=1,其他程序無法進入臨界區。
缺點:使用了忙等待,無法進入臨界區的程序一直在執行指令,消耗cpu時間。
2.1.3 訊號量(semaphore)
訊號量是程序間傳遞訊號的乙個整數值。只能進行三種操作,初始化、遞減和增加。
1)乙個訊號量s可以被初始化為非負整數
2)wait(s)操作使s減1。如果s變成負數,則將執行wait的程序阻塞,放進s的等待佇列中。如果s為正,則繼續執行(進入臨界區)
3)signal(s)使s增加1。如果s小於等於0,則說明在s的等待佇列中有程序被阻塞,所以將其中乙個程序解除阻塞。
開始時,s被初始化為正數,s等於能同時進入臨界區的解除程序數,當進入臨界區的程序數超過初始值後,執行wait()的程序進入等待佇列,並阻塞(避免了忙等待),s值小於0,其絕對值|s|等於等待佇列中程序數。
訊號量的實現:
因為訊號量也是共享資源,對其操作也需要互斥,可以用cmp&swap實現。
如:wait(s)
while(compare_and_swap(s.flag,0,1)==1);
s.count--;
if(s.count<0)
{ //阻塞該程序 s.flag=0
s.flag=0;//讓其他程序通過while
signal類似。
這裡也需要忙等待,但是這裡忙等待的物件是wait和signal,他們的操作相對於臨界區來說很短,所以開銷可以接受。
總結:
比如臨界區c是廁所,訊號量s表示同時能進廁所的人數。
不使用訊號量時:
第乙個人進入c後,其他人只能在外面等待,並且不斷詢問裡面的人好了沒。
使用訊號量:
增加了房間s和b,要上廁所時,先到s裡面那c的鑰匙(訊號量的初始值即為鑰匙總量),拿到的進入c,拿不到的進入b休息室(阻塞)。s每次也只能通過乙個人,其他人也需要在s外面忙等待,但通過s的時間遠小於c,所以等待時間不長。從c出來後,如果b中有人,就將鑰匙給b中的人,即當s.count<=0是解除阻塞程序。
互斥與併發 2 訊號量
1.訊號量 semaphore 為了達到訊號量的預期效果,可把訊號量看做具有整數值得變數,在它之上定義三個操作 1 乙個訊號量可以初始化為乙個非負數 2 semwait操作使訊號量減1 國內的教材將該操作稱為p 如果變成負數,那麼執行semwait的程序被阻塞,並被移入阻塞佇列。否則該程序繼續執行 ...
互斥量與訊號量(互斥與同步)
互斥量 mutex 互斥量表現互斥現象的資料結構,也被當作二元訊號燈。乙個互斥基本上是乙個多工敏感的二元訊號,它能用作同步多工的行為,它常用作保護從中斷來的臨界段 並且在共享同步使用的資源。mutex本質上說就是一把鎖,提供對資源的獨佔訪問,所以mutex主要的作用是用於互斥。mutex物件的值,只...
訊號量 互斥量
lonelycatcher if only as first.來自 訊號量用在多執行緒多工同步的,乙個執行緒完成了某乙個動作就通過訊號量告訴別的執行緒,別的執行緒再進行某些動作 大家都在semtake的時候,就阻塞在 而互斥鎖是用在多執行緒多工互斥的,乙個執行緒占用了某乙個資源,那麼別的執行緒就無法...