1. 程式人生 > >程序間通訊(IPC)之訊號量

程序間通訊(IPC)之訊號量

★IPC方法包括管道(PIPE)、訊息佇列(Message_Queue)、訊號量(semaphore)、共用記憶體

(ShareMemory)以及套接字(Socket)。程序間通訊主要包括了管道、系統IPC(包括了訊息佇列、訊號以

及共享儲存)、套接字(SOCKET)。此文將探討訊號量機制的相關內容。

★訊號量:

訊號量不以傳輸資料為目的,其本質是一種資料操作鎖,本身不具有資料交換的功能,而是通過控制其他的通訊

資源(例如檔案、外設等)來實現程序間通訊,只是一種外部資源的標誌。訊號量在此過程中負責資料操作的互斥,

同步等功能。其建立和初始化的過程不能保證均是基於原子層面的操作。



在此之前,須引出同步和互斥的有關概念。




①臨界資源:不同程序訪問的同一資源稱為臨界資源。

②臨界區:兩個或多個程序訪問臨界資源的程式碼稱為臨界區。



★★★★★★★★★★★★★★★★★★★★★★                   1.    什麼是互斥                          ★★★★★★★★★★★★★★★★★★★★

     多程序環境下,若一個程序已進入臨界區訪問臨界資源時,其他程序不得進入臨界區。該程序獨自享有臨界區全

部臨界資源,對於其他程序具有強烈的排斥性。這種只允許一個執行流訪問臨界資源的情形稱為互斥。

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★



★★★★★★★★★★★★★★★★★★★★★                      2.

     什麼是同步                           ★★★★★★★★★★★★★★★★★★★★

    在多執行流訪問臨界資源時,對某一執行流頻繁訪問臨界資源而長時間享有獨佔性時,對於較之不頻繁訪問臨

資源的執行流來說要等待的時間過久,所以互斥雖能保證各程序進入臨界區訪問臨界資源時的資料正確性,但卻並

非最高效的方法。所以在互斥基礎上,訪問臨界區的臨界資源時各程序產生一定的訪問順序,這種順序性稱為同步。

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★


⑴表示過程:當請求一個使用訊號量來表示的資源時,程序需要先讀取訊號量的值來判斷資源是否可用。大於0,資

源可以請求,等於0,無資源可用,程序會進入睡眠狀態直至資源可用。

⑵工作原理:由於訊號量只能進行兩種操作等待和傳送訊號,即P(sv)和V(sv)。P(sv):如果sv的值大於

零,就將其減一;如果它的值為零,就掛起該程序的執V(sv):如果有其他程序因等待sv而被掛起,就讓它恢復運

行,如果沒有程序因等待sv而掛起,就將其加1。





★linux為訊號量機制提供了許多關於訊號量操作的函式,這些函式用來對成組的訊號量進行操作,其宣告在標頭檔案

<sys/sem.h>中。


注:從上圖可以看出,在sem_structure中也有關於struct_ipc_perm的結構體成員(紅框部分),這說明訊號量同

樣是IPC下的程序間通訊方式之一。 注:雖說訊號量的本質不具有資料交換的功能,但是其在程序間通訊中負責資料

操作的互斥及同步的功能,從這一點上來看,訊號量也是程序間通訊的一種方式,只是它不像管道,訊息佇列、共享

記憶體那樣嚴格。




★在這眾多的關於訊號量的操作函式中,semctl是比較特殊且尤為重要的函式。


▲semctl()在semid標識的訊號量集上,或者該集合的第semnum個訊號量上執行cmd指定的控制命令(訊號量集合

索引起始於零)。根據cmd不同,這個函式有三個或四個參數。當有四個引數時,第四個引數的型別是union。見下

圖(紅線部分):


★通過訊號量機制的設定讓終端的父子程序分別輸出A和B字元時交叉顯示。

程式碼:

①comm.h:宣告所涉及的函式的介面。


注:可以看到,該檔案中不僅定義了semctl函式中的聯合體(貼上過來的),並且還定義了訊號量的建立,獲取,清

除,初始化及重置,以及P和V操作的介面函式。

②comm.c:對.h檔案中宣告的函式介面的具體實現。

           


③test_sem.c:主函式---------->測試用例                     

                                                  

Makefile:程式的自動化編譯


注:主函式中用到了usleep控制等待毫秒數量級,sleep輸出長串字元太慢,因為要短時看到父子程序輸出的字元是

否是按規律先後輸出(有無交叉),所以通過usleep縮短時間,其值是隨便給的,並無規定。

執行結果: