程序間通訊 訊號量

2021-08-19 18:05:02 字數 4224 閱讀 5474

更多linux知識點:linux目錄索引

1. 什麼是訊號量

訊號量的本質是資料操作鎖,它本身不具有資料交換的功能,而是通過控制其他的通訊資源(檔案,外部裝置)來實現程序間通訊,它本身只是一種外部資源的標識。訊號量在此過程中負責資料操作的互斥、同步等功能。

個人理解:訊號量就是具有原子性的計數器,當使用了資源時,計數器就要減一,表示可用的資源就少了乙個,當用完這個資源將其還回去時,計數器加一,表示可用的資源又多了乙個

2. 訊號量的工作原理

由於訊號量只能進行兩種操作等待和傳送訊號,即p(sv)和v(sv),他們的行為是這樣的:

p(sv):如果sv的值大於零,就給它減1;如果它的值為零,就掛起該程序的執行

v(sv):如果有其他程序因等待sv而被掛起,就讓它恢復執行,如果沒有程序因等待sv而掛起,就給它加1.

例子:

假設桌子上只有乙個盤子,那我們就記可用盤子的數量為count=1,小明現在將這個盤子拿走,則桌子上就沒有盤子,(執行p操作)count = 0,此時小紅也想從桌子上拿盤子,發現count = 0,沒有盤子,他就在這等著,過了一會,小明用完盤子並將其放回了桌子(執行v操作),小紅此時發現count = 1(表示有盤子),就拿走盤子(執行p操作)

3. 對於訊號量的操作

建立

#include 

#include

#include

//如果訊號量不存在就建立,存在就開啟

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

//返回值:函式成功返回乙個相應訊號識別符號,失敗返回-1

引數:

key:訊號量的識別符號,一般由ftok函式獲得

nsems:訊號量的個數,表示你要建立幾個訊號量

sem***:一組標誌,當想要當訊號量不存在時建立乙個新的訊號量,可以和值ipc_creat做按位或操作。設定了ipc_creat標誌後,即使給出的鍵是乙個已有訊號量的鍵,也不會產生錯誤。而ipc_creat | ipc_excl則可以建立乙個新的,唯一的訊號量,如果訊號量已存在,返回乙個錯誤。

pv操作

#include 

#include

#include

//改變訊號量的值,也就是執行pv操作

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

引數:訊號量的識別符號semget

semget的返回值,訊號量的識別符號

引數:sembuf結構體

struct sembuf;
引數:訊號量的個數

表示你要操作幾個訊號量

控制

#include 

#include

#include

int semctl(int semid, int semnum, int cmd, union semun arg);

//返回值:成功返回訊號量集的識別符號,失敗返回-1

引數:訊號量的識別符號semid

semget的返回值

引數:訊號量的編號semnum

要操作訊號在訊號集中的編號。編號從0開始。

引數:選項cmd

cmd: 命令,表示要進行的操作。(setval:設定初值;getval:獲取初值

命令

解釋ipc_stat

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

ipc_set

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

getall

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

getncnt

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

getpid

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

getzcnt

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

setall

與getall正好相反

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

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

ipc_rmid從核心中刪除訊號量集合

引數:聯合體arg

union semun  arg;
4. 例項:利用訊號量解決哲學家就餐問題問題描述:

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

問題分析:

當5個哲學家程序併發執行時,某個時刻恰好每個哲學家程序都執行申請筷子,並且成功申請到第i支筷子(相當於5個哲學家同時拿起他左邊的筷子), 接著他們又都執行申請右邊筷子, 申請第i+1支筷子。此時每個哲學家僅拿到一支筷子, 另外一支只得無限等待下去, 引起死鎖。

解決思路

對每個哲學家和筷子進行編號:0~4

對每個筷子都設定乙個訊號量(計數器)

每個哲學家每次取筷子時,同意給他左右兩個筷子,即自己編號(num)和 num+1,並且對這兩個筷子執行p操作,其他哲學家取筷子時就在等待

4.當用完兩個筷子就將其歸還,執行v操作,以便其他哲學家進行使用

這樣保證每個哲學家拿筷子時都能拿到足夠的筷子,避免死鎖

4. **:

#include 

#include

#include

#include

#include

union su

;int semid;

void p(int num),};

semop(semid,array,2);

}void v(int num),};

semop(semid,array,2);

}void zxj(int num)

}//哲學家就餐,先建立訊號量,用於管理筷子,在建立5個程序,表示哲學家

int main()

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

if(semid < 0)

int i=0;//對5個訊號量進行初始化,每個訊號量初始化為1

for(; i < 5;++i)

;semctl(semid,i,setval,s);

}int num = 0;

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

zxj(num);

return

0; }

結果:

程序間通訊 訊號量

ipc識別符號和關鍵字 在終端輸入ipcs,可以看到目前系統中所有的ipc資訊 第一列的key就是ipc的關鍵字,第二列是ipc的識別符號。ftok 函式用於獲得乙個ipc的關鍵字,其函式原型是 key t ftok const char pathname,int proj id 下面是乙個訊號量的...

程序間通訊 訊號量

system ipc中,對於每乙個新建的訊號量 訊息佇列 共享記憶體,都有乙個在整個系統中唯一的識別符號。每個標識也都有唯一對應的關鍵字,關鍵字的資料型別為ket t 在終端輸入命令 ipcs 可以看到目前系統中所有的ipc資訊 共享記憶體段 鍵 shmid 擁有者 許可權 位元組 nattch 狀...

程序間通訊 訊號量

訊號量不是ipc 機構,它只是乙個計數器用於不同程序之間或同一程序不同執行緒之間的同步,型別 二元訊號 值為0或 1,1說明有可用資源,0說明此時資源占用,其他程序需等待。計數訊號量 表示可用資源數量。計數訊號量集 由乙個或多個訊號量組成的集合,每乙個都是計數訊號量。訊號量資料結構 include ...