程序間通訊之訊號量

2021-08-17 14:00:03 字數 3279 閱讀 1693

訊號量也是三種xsi ipc之一,不過與訊息佇列和共享記憶體不同的是作為臨界資源的訊號量是以另一種臨界資源的計數器的面目出現的。其基本作用機制為,為某種臨界資源設定一定數量的訊號量,當某個程序占用乙份臨界資源時訊號量就減少相應的數值,當訊號量為0時沒有得到臨界資源的程序就暫時性的進入「休眠」狀態,待占用資源的程序將資源還回去後訊號量增加,其他程序被喚醒,就又可以使用臨界資源,這樣就實現了臨界資源的同步互斥。

首先介紹建立與訪問訊號量的函式:

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

返回值:成功返回該訊號集的標識碼,失敗返回-1。

引數:

key: 訊號集的名字 。

nsems: 訊號集中訊號量的個數。

sem***: 由九個許可權標誌構成,它們的⽤用法和建立⽂檔案時使⽤用的mode模式標誌是⼀樣的。

控制函式(常用於初始化和刪除乙個訊號量):

int semctl(int semid, int semnum, int cmd, …);

返回值:成功返回0,失敗返回-1。

引數:

semid: 由semget返回的訊號集標識碼。

semnum: 訊號集中訊號量的序號。

cmd:將要採取的動作,下圖(來自unix環境高階程式設計)是cmd可命令,初始化訊號量用setval命令,刪除訊號量用ipc_rmid命令。

最後⼀乙個引數根據命令不同⽽而不同,如果要初始化乙個訊號量,則要用到乙個結構:

union semun

; 進行初始化時除了第三個引數為setval外,第四個引數必須是這個聯合的乙個物件,並且要對聯合中的val賦予準備初始化的數值。

訊號量操作函式:

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

返回值:成功返回0,失敗返回-1。

引數:

semid: 是該訊號量的標識碼,也就是semget函式的返回值。

sops: 是個指向⼀乙個結構數值的指標。

nsops: 訊號量的個數。

對訊號量進行操作時必須要用到乙個結構體:

struct sembuf

; sem_num是訊號量的編號。

sem_op是訊號量⼀一次pv操作時加減的數值,⼀一般只會⽤用到兩個值:乙個是「-1」,也就是p操作,等待訊號量變得可⽤用,另⼀乙個是「+1」,也就是我們的v操作,發出訊號量已經變得可⽤。

sem_flag的兩個取值是ipc_nowait或sem_undo。

最常用的是二元訊號量,也叫雙態訊號量,它控制著單個資源,初始值為1,當乙個程序占用資源後訊號量即變為0,其他程序只能等待訊號量變回1。用**實現二元訊號量:

當兩個程序同時向顯示器進行輸出時,顯示器也是就是一種臨界資源。我們用兩個程序同時向螢幕列印字元(子程序列印字元a,父程序列印字元b),如果不作任何處理,那麼列印的效果將是這樣的:

而我們要的效果是這樣的:

即每個程序列印的字元是兩個兩個挨著的,現在用**來實現:

makefile檔案:

.phony : all

all : test

test : test.c comm.c

gcc -o test test.c comm.c

.phony : clean

clean :

rm -f test

comm.h檔案:

#ifndef __comm_h_

#define __comm_h_

#include

#include

#include

#include

#include

#include

#include

#define pathname "."

#define proj_id 0x6666

union semun

;int creatsem(int nsems);

int getsem(int nsems);

int initsem(int semid, int nums, int initval);

int destorysem(int semid);

int p(int semid, int who);

int v(int semid, int who);

#endif //__comm_h_

comm.c檔案:

#include "comm.h"

static int _getcommsem(int nsems, int flag)

int semid = semget(key, nsems, flag);

if(semid < 0)

return semid;

}int creatsem(int nsems)

int getsem(int nsems)

int initsem(int semid, int nums, int initval)

}int destorysem(int semid)

return0;}

static int commpv(int semid, int who, int op)

return0;}

int p(int semid, int who)

int v(int semid, int who)

test.c檔案:

#include "comm.h"

int main()

else

if(pid == 0)

}else

wait(null);

}destorysem(semid);

return

0;}

這是乙個訊號量的簡單應用,我們知道共享記憶體ipc不具備同步互斥功能,但它又是最快的ipc,我們可以在共享記憶體上加入訊號量,這樣就實現即快速又安全的程序間通訊,在這裡就不實現了,如果有時間後面實現了再發出來。

程序間通訊之訊號量

訊號量的本質是一種資料操作鎖,其本身不具有資料交換的能力,而是通過控制其他的通訊資源 檔案 外部裝置 來實現程序間通訊,它本身只是一種外部資源的標識。訊號量在此過程中負責資料的互斥 同步等功能。當請求乙個訊號量來表示資源時,程序需要讀取訊號量的值來判斷資源是否可用。大於0,資源可以請求,等於0,無資...

程序間通訊之訊號量

訊號量的本質是一種資料操控鎖,它本身不具有資料交換的功能,而是通過來控制其他的通訊資源來實現程序間通訊的,訊號主要負責資料的同步與互斥功能。程序請求乙個使用訊號量來表示的資源時,首先要讀取訊號量的值來判斷資源是否能被使用,若訊號量的值大於0,資源可用,等於0,無資源可用,同時程序會進入睡眠狀態,直到...

程序間通訊之 訊號量

訊號量相當於記錄資源能同時被多少個程序訪問。訊號量的作用 程序間同步控制。訊號量有乙個初值,每當有程序申請使用訊號量,就會通過乙個p操作對訊號量進行 1操作,當計數器減到0的時候就說明沒有資源了,其他程序要想訪問就必須等待,當該程序執行完這段工作之後,就會執行v操作,即對訊號量進行 1操作。標頭檔案...