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

2021-08-09 14:36:16 字數 3251 閱讀 6766

一. 訊號量

在談論訊號量之前,先要提到臨界資源臨界區的概念,臨界資源是指多個程序訪問但乙個時間段內只允許乙個程序獨佔的資源,而臨界區是指多個程序訪問臨界資源的這一段公共的**。

訊號量的本質是一種資料操作鎖,也可以說就是乙個計數器,它本身並不能提供對程序間的通訊,而是通過控制某一資源來完成程序間的互斥和同步,比如當乙個程序請求某一用訊號量來表示的臨界資源時,先要進行檢查該資源的訊號量,若訊號量大於零,表示有資源可用,若訊號量等於零,則表示有其他程序正在使用該資源,則申請的程序需要掛起等待。

訊號量的存在其實就是給程序間的訊號,表示該資源可不可以被訪問,因此也是作為程序間通訊的一種方式。

二. 訊號量的建立與銷毀

訊號量和前面提到的管道、訊息佇列是一樣的,都是需要函式建立來獲取的:

函式引數中,key在訊息佇列中就提到過,它可以被認為是乙個埠號,用ftok函式來建立:

pathanme是檔案路徑名,而proj_id是乙個整數,二者結合可轉換成乙個整數標識。

nsems表示要建立多少個訊號量,因為semget建立的是乙個訊號量集,可能有多個資源需要被標識;

sem***也和訊息佇列中的msg***一樣,有兩個選項ipc_creatipc_excl,當兩個一起使用時可以保證訊號量集是新建立的,建立失敗返回-1;當ipc_creat單獨使用時若訊號量集已存在則返回已存在的,若不存在則新建乙個;

當semget建立訊號量集成功就會返回乙個訊號量集的sem_id的整數,若失敗返回-1;

訊號量集建立出來了當然使用完成之後也是需要銷毀的:

函式引數中第乙個當然是要刪除的訊號量集的sem_id;

semnum表示要對訊號量集中的第幾個訊號量進行cmd操作;

cmd操作為ipc_rmid刪除

下面要提到cmd的乙個操作setval,可以用來初始化訊號量,可以看到semctl函式中最後一項是可變引數列表,也就是說semctl的引數可以為三個或四個,當為四個引數時,最後乙個必須是乙個聯合體,要按如下定義:

這個聯合體不一定定義在某個系統標頭檔案中,若沒有,則需要使用者自己定義;聯合中第乙個整形val就是需要初始化的值;至於後面的buf是ipc_stst、ipc_set使用的快取區;array是getall、setall所使用的陣列及_buf表示ipc_info(linux特有)使用的快取區;以上這些都是需要使用者自定的。

三. 訊號量的p操作與v操作

當乙個程序要申請某個資源時,系統會先檢查該資源的訊號量是否大於零,若大於零表示有資源可用,這時該程序就要使用該資源,因此應該將該資源的訊號量減為零,也就是p操作;當程序使用完資源之後要將其放回供其他程序使用,此時就應該將訊號量的值加回為原值,也就是v操作了:

函式引數中,

semid就不說了是表示要進行哪乙個訊號量操作的sem_id;

sops是乙個結構體指標,該結構體應如下定義:

sem_num表示是訊號量集中的第幾個訊號量;

sem_op表示要進行什麼樣的操作,小於零表示減,大於零表示加,等於0是;

sem_***有兩個選項,ipc_nowaitsem_undo,ipc_nowait表示如果沒有資源可用則不阻塞直接返回       eagain,如果乙個操作指定為sem_undo,當程序終止的時候它就會自動撤消該操作恢復原來值;

nsops表示有幾個要操作的訊號量數;

和前面談訊息佇列時一樣,將訊號量所需要的函式封裝起來:

先是訊號量的建立,為了區別是新建立的訊號量還是獲得已存在的訊號量,可以根據傳參的不同封裝兩個函式creat_sem和get_sem,同時還要有初始化:

接下來是函式p、v操作和銷毀訊號量:

下面就可以先寫乙個栗子,我們知道顯示器在一段時間內只允許乙個程序訪問時臨界資源,當沒有訊號量標識時,兩個程序同時向顯示器輸出會有什麼樣的結果呢:

執行程式可以看到a和b是亂序輸出的,也就是當兩個程序同時訪問乙個資源時產生了衝突;

下面就可以將程式改為運用訊號量完成程序間通訊,也就是當兩個程序同時訪問臨界資源時有乙個交流的過程,你在用我就等著我在用你就等著:

上面的程式中一定要注意,fork子程序應該在父程序creat_sem之後,否則若子程序先執行get_sem出了訊號量,之後父程序在執行去creat_sem就得不到訊號量了,執行程式就會得到如下aabb交錯有序的結果,如此也就完成了程序間的另一種通訊方式:

最後要說的一點就是,對訊號量的操作是原子性的,因為並沒有中間值,但是在訊號量的建立及初始化就不一定是原子的了。

《完》本文出自 「敲完**好睡覺zzz」 部落格,請務必保留此出處

程序間通訊IPC 訊號量

訊號量 訊號量 主要來實現程序間或執行緒間的同步 也可以實現互斥 訊號量的值 表示資源的可用量。訊號量操作流程 1 建立乙個訊號量集合 param 2 訊號量集合中訊號量的個數 int semid int semget key t key,int nsems,int sem semid semget...

IPC程序間通訊(訊號量)

訊號量是乙個計數器,用於為多個程序提供對共享資料物件的訪問。訊號量和p v原語操作是由dijkstra 迪傑斯特拉 所提出的。執行p操作時,將該程序狀態設定為等待狀態,並把 該程序的pcb插入相應的等待佇列s.queue末尾 執行v操作時,喚醒相應等待佇列s.queue中等待的乙個程序 改變其狀態為...

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

三 demo 父子程序的訊號量 在對於臨界區資源管理的過程中,多個程式同時訪問乙個共享資源經常容易引發一系列問題 如死鎖,結果不唯一等等,使用訊號量,來解決程序或執行緒間共享資源引發的同步問題。讓多個程序通過特殊變數展開互動,乙個程序在某乙個關鍵點上被迫停止執行直至接收到對應的特殊變數值,通過這一措...