Linux 程序間通訊 訊號量

2021-08-19 17:12:42 字數 2635 閱讀 9254

linux學習目錄

1、 什麼是訊號量?

在對於臨界區資源管理過程中,為了防止多個程式同時訪問乙個共享資源而引發的一系列問題。比如:死鎖。

為了解決這種問題,巨人們就發明了訊號量。

訊號量就是為了解決在乙個臨界區只有乙個程序訪問它,也就是說訊號量相當於交警,來協調程序對共享資源有序的訪問而不造成死鎖等行為。

訊號量是乙個特殊的變數,程式對它訪問都是原子操作,並且她只能進行兩種操作,等待(p訊號量)和傳送(v訊號量) 。

p(sv):如果sv的值大於0,說明資源可用,就給它減1,如果它等於0,就掛起該程序說明資源不可用,直到資源可用。

v(sv):如果sv值大於0,並且有其他程序因為等待sv而被掛起,則該程序恢復執行,如果沒有程序等待,則sv加1

2、訊號量的函式操作

int

semget(key_t key, int nsems, int sem***);

int

semop(int semid, struct sembuf *sops, unsigned nsops);

nsops:陣列元素個數

2.3、semctl函式

作用:控制訊號量集

int semctl(int semid,int senum,int cmd,...)

返回值:訊號量的當前值

命令

解釋ipc_stat

從訊號量集上檢索semid_ds結構,並存到semun聯合體引數的成員buf的位址中

ipc_set

設定乙個訊號量集合的semid_ds結構中ipc_perm域的值,並從semun的buf中取出值

ipc_rmid

從核心中刪除訊號量集合

getall

從訊號量集合中獲得所有訊號量的值,並把其整數值存到semun聯合體成員的乙個指標陣列中

getncnt

返回當前等待資源的程序個數

getpid

返回最後乙個執行系統呼叫semop()程序的pid

getval

返回訊號量集合內單個訊號量的值

getzcnt

返回當前等待100%資源利用的程序個數

setall

與getall正好相反

setval

用聯合體中val成員的值設定訊號量集合中單個訊號量的值

對於該函式,只有當cmd取某些特定的值的時候,才會使用到第4個引數,第4個引數它通常是乙個union semum結構,定義如下

union semun

3、哲學家就餐問題:

假設有五位哲學家圍坐在一張圓形餐桌旁,做以下兩件事情之一:吃飯,或者思考。吃東西的時候,他們就停止思考,思考的時候也停止吃東西。餐桌中間有一大碗公尺飯,每兩個哲學家之間有乙隻筷子。因為用乙隻筷子很難吃到公尺飯,所以假設哲學家必須用兩隻筷子吃東西。他們只能使用自己左右手邊的那兩隻筷子。所以現在就出現了問題。

- 3.2:問題分析

當五個哲學家在某個時刻同時申請到拿筷子操作時,並且申請成功了,這時他們都拿到了左手邊的乙隻筷子,但是當他們申請右手邊筷子時,發現右手邊筷子沒有資源只能繼續等,這時五個哲學家都在等,這樣就產生了死鎖。

- 3.3 : 解決思路

3.3.1:給每個哲學家和筷子進行編號,從0開始到4,因為senum中第乙個訊號量的下標是從0開始的。

3.3.2:每個筷子代表乙個訊號量

3.3.3:每個哲學家在取筷子時每次拿左右兩隻筷子,並且執行p操作使其它哲學家處於等待狀態,直到該哲學家吃飽,放下筷子(釋放資源)時,其它哲學家才可以拿筷子,從而繼續迴圈。

3.3.4:通過訊號量以及pv操作保證每次只有乙個哲學家拿一雙筷子,其它哲學家都等待,直到該哲學家釋放資源。從而避免死鎖。

#include

#include

#include

#include

#include

#include

int id;

union semun

;void p(int num)

,

};semop(id,sops,2);

}void v(int num)

,

};semop(id,sops,2);

}void zxj(int num)

}int main()

id = semget(key,5,ipc_creat|0644);

if(id == -1)

union semun su = ;//每個哲學家的筷子數為1

int i = 0;

for(i = 0;i < 5 ; i++)

int num = 0;

for(i = 1;i < 5; i++ )

}zxj(num);

return

0;}

linux 訊號量(程序間通訊)

將使用乙個程式來演示訊號量的使用,程式用pv操作控制訊號量,以操作臨界區,p操作讓訊號量減1,v操作讓訊號量加1,而pv操作之間的 即為臨界區關鍵 每次只能由乙個程序訪問。程式建立出乙個子程序,在兩個程序中分別有一段臨界區關鍵 實現的功能都是不斷的順序輸出0 9的字元。保證程序間同步 plain v...

linux 程序間通訊 訊號量

例項中首先使用fork 建立乙個子程序,在父程序呼叫kill 之前,在子程序中使用raise 向自身傳送sigstop訊號,是子程序暫停。接下來使用kill 向子程序傳送訊號 ngnsvr9 none home xionghailong example cat kill raise.c includ...

Linux程序間通訊 訊號量

此處只涉及利用 二進位制訊號量 只用0和1 完成 控制線程順序 為中心的同步方法。訊號量的建立和銷毀函式 pshared引數超出我們關注的範圍,預設向其傳遞0.訊號量相當於互斥量lock,unlock的函式 呼叫sem init函式時,作業系統將建立訊號量物件,此物件中記錄著 訊號量值 整數。該值在...