1. 程式人生 > >一起talk C栗子吧(第一百回:C語言例項--使用訊號量進行程序間同步與互斥一)

一起talk C栗子吧(第一百回:C語言例項--使用訊號量進行程序間同步與互斥一)

各位看官們,大家好,上一回中咱們說的是程序間同步與互斥的例子,這一回咱們說的例子是:使用訊號量進行程序間同步與互斥。閒話休提,言歸正轉。讓我們一起talk C栗子吧!

看官們,訊號量是由著名電腦科學家迪傑斯特拉(Dijkstra)提出的一種概念,專門用來解決程序間同步與互斥。在他提出的概念中訊號量是一個非負整數值.

訊號量的操作只能有兩種原子操作

  • 等待訊號;
  • 傳送訊號。

“什麼是原子操作呢?”臺下有看官在提問,原子操作就是指某個動作在執行時不能被其它動作中斷,它會一直進行,直到該動作執行完成為止。比如,我們在寫程式碼的時候,突然收到一封郵件,這時候系統會暫時中斷寫程式碼的程式vim(我用的是vim),然後讓郵箱客戶端發一個收到郵件的通知,然後再恢復到vim寫程式碼的動作中。例子中使用vim寫程式碼的動作就不是一個原子操作,只有它不能被其它動作中斷時,它才是一個原子操作。接下來我們介紹對訊號量的原子操作。

等待訊號

等待訊號也叫P操作。例P(sem)表示對訊號量sem進行P操作。

  • 如果sem的值大於零,p操作會把sem的值減去1;
  • 如果sem的值等於零,那麼掛起執行p操作的程序;

傳送訊號

傳送訊號也叫V操作。例如V(sem)表示對訊號量sem進行V操作。

  • 如果有程序在因為等待sem而被掛起,那麼喚醒等待的程序;
  • 如果沒有程序因為等待sem而被掛起,那麼把sem的值加上1.

虛擬碼

下面是使用訊號量進行程序同步與互斥的虛擬碼

nocritical code     //非臨界區的程式碼
P(sem);             //執行P操作,進入臨界區,執行臨界區中的程式碼
{ critical code; //臨界區程式碼 do something } V(sem); //執行V操作,離開臨界區 nocritical code //非臨界區的程式碼

假設上面虛擬碼中的訊號量sem值為1,程序A開始執行上面的虛擬碼,在進入臨界區前先對訊號量進行P操作,這時sem的值變為0,然後程序A執行臨界區中的程式碼,這個時候程序B也開始執行上面的虛擬碼,在進入臨界區前先對訊號量進行P操作,這時程序A還沒有離開臨界區,訊號量sem的值為零,程序B就會被掛起,直到程序A離開臨界區執行V操作時,sem的值變為1,然後喚醒等待sem的程序B,接著程序B進入臨界區並且執行臨界區中的程式碼。

大家可以看到,通過訊號量的P/V操作,可以保證在同一個時間內,只有一個程序在執行臨界區中的程式碼,也就是說實現了程序的同步與互斥。

看官們,本章回中就不寫程式碼了,因為我們還沒有介如何使用訊號量,在後面的章回中,我們會介紹訊號量的操作,並且結合具體的例子,把虛擬碼轉換成實際的程式碼。

各位看官,關於使用訊號量進行程序間同步與互斥的例子咱們就說到這裡。欲知後面還有什麼例子,且聽下回分解 。