Linux的訊號量

2021-10-10 02:25:51 字數 4100 閱讀 5242

訊號量(semaphore)與已經介紹過的 ipc 結構不同,它是乙個計數器。訊號量用於實現程序間的互斥與同步,而不是用於儲存程序間通訊資料。

**1、訊號量用於程序間同步,若要在程序間傳遞資料需要結合共享記憶體。

2、訊號量基於作業系統的 pv 操作,程式對訊號量的操作都是原子操作。

3、每次對訊號量的 pv 操作不僅限於對訊號量值加 1 或減 1,而且可以加減任意正整數。

4、支援訊號量組。

例子:就像乙個房間,訊號量相當於開門的鑰匙,房間相當於連線資源(一次僅允許乙個程序使用的資源;如:a程序正在使用臨界資源,b程序就無法使用,等a程序完成後才行。)

在linux中有許多的訊號量集,

p操作:拿鎖;v操作:放回鎖;

****

最簡單的訊號量是只能取 0 和 1 的變數,這也是訊號量最常見的一種形式,叫做二值訊號量(binary semaphore)。而可以取多個正整數的訊號量被稱為通用訊號量。

linux 下的訊號量函式都是在通用的訊號量陣列上進行操作,而不是在乙個單一的二值訊號量上進行操作。

1 #include 

2// 建立或獲取乙個訊號量組:若成功返回訊號量集id,失敗返回-1

3int

semget

(key_t key,

int num_sems,

int sem_flags);4

// 對訊號量組進行操作,改變訊號量的值:成功返回0,失敗返回-1

5int

semop

(int semid,

struct sembuf semoparray[

], size_t numops);6

// 控制訊號量的相關資訊

7int

semctl

(int semid,

int sem_num,

int cmd,..

.);

semget建立新的訊號量集合時,必須指定集合中訊號量的個數(即num_sems),通常為1; 如果是引用乙個現有的集合,則將num_sems指定為 0 。

所需標頭檔案:

#include

#include

#include

函式返回值:成功:返回訊號量集的識別符號;出錯:-1,錯誤原因存於error中

key:0(ipc_private):會建立新訊號量集物件,key大於0的32位整數:視引數sem***來確定操作,通常要求此值**於ftok返回的ipc鍵值

nsems:建立訊號量集中訊號量的個數,該引數只在建立訊號量集時有效

msg***:

0:取訊號量集識別符號,若不存在則函式會報錯

ipc_creat:當sem***&ipc_creat為真時,如果核心中不存在鍵值與key相等的訊號量集,則新建乙個訊號量集;如果存在這樣的訊號量集,返回此訊號量集的識別符號

ipc_creat|ipc_excl:如果核心中不存在鍵值與key相等的訊號量集,則新建乙個訊息佇列;如果存在這樣的訊號量集則報錯

在semop函式中,sembuf結構的定義如下:

1

struct sembuf

2

sem_op 是一次操作中的訊號量的改變量:

若sem_op > 0,表示程序釋放相應的資源數,將 sem_op 的值加到訊號量的值上。如果有程序正在休眠等待此訊號量,則換行它們。

若sem_op < 0,請求 sem_op 的絕對值的資源。

如果相應的資源數可以滿足請求,則將該訊號量的值減去sem_op的絕對值,函式成功返回。

當相應的資源數不能滿足請求時,這個操作與sem_***有關。

sem_*** 指定ipc_nowait,則semop函式出錯返回eagain。

sem_*** 沒有指定ipc_nowait,則將該訊號量的semncnt值加1,然後程序掛起直到下述情況發生:

1、當相應的資源數可以滿足請求,此訊號量的semncnt值減1,該訊號量的值減去sem_op的絕對值。成功返回;

2、此訊號量被刪除,函式smeop出錯返回eidrm;

3、程序捕捉到訊號,並從訊號處理函式返回,此情況下將此訊號量的semncnt值減1,函式semop出錯返回eintr

成功:返回訊號量集的識別符號;出錯:-1,錯誤原因存於error中。

在semctl函式中的命令有多種,這裡就說兩個常用的:

1、setval:用於初始化訊號量為乙個已知的值。所需要的值作為聯合semun的val成員來傳遞。在訊號量第一次使用之前需要設定訊號量。

2、ipc_rmid:刪除乙個訊號量集合。如果不刪除訊號量,它將繼續在系統中存在,即使程式已經退出,它可能在你下次執行此程式時引發問題,而且訊號量是一種有限的資源。

訊號量(父子之間通訊):

#include

"stdio.h"

#include

#include

#include

// int semget(key_t key, int num_sems, int sem_flags);

// // 對訊號量組進行操作,改變訊號量的值:成功返回0,失敗返回-1

// int semop(int semid, struct sembuf semoparray, size_t numops);

// // 控制訊號量的相關資訊

// int semctl(int semid, int sem_num, int cmd, ...);

union semun

;void

pgetkey

(int id)

void

vputbackkey

(int id)

intmain()

else

if(pid==0)

else

}

共享記憶體與訊號量:

1 #include

2 #include

3 #include45

// 聯合體,用於semctl初始化

6union semun

7;1213

// 初始化訊號量

14int

init_sem

(int sem_id,

int value)

1523

return0;

24}2526

// p操作:

27// 若訊號量值為1,獲取資源並將訊號量值-1

28// 若訊號量值為0,程序掛起等待

29int

sem_p

(int sem_id)

3041

return0;

42}4344

// v操作:

45// 釋放資源並將訊號量值+1

46// 如果有程序正在掛起等待,則喚醒它們

47int

sem_v

(int sem_id)

4859

return0;

60}6162

// 刪除訊號量集

63int

del_sem

(int sem_id)

6471

return0;

72}7374

75int

main()

7687

88// 建立訊號量集,其中只有乙個訊號量

89if

((sem_id =

semget

(key,

1, ipc_creat|

0666))

==-1)

9094

95// 初始化:初值設為0資源被占用

96init_sem

(sem_id,0)

;9798if

((pid =

fork()

)==-1

)99perror

("fork error");

100else

if(pid ==0)

/*子程序*/

101106

else

/*父程序*/

107113

return0;

114}

訊號量 二值訊號量

訊號量 二值訊號量 訊號量是作業系統的重要部分,訊號量一般用來進行資源管理和任務同步。freertos中訊號量分為二值訊號量 互斥訊號量 計數訊號量和遞迴互斥訊號量,應用場景各不同。二值訊號量通常用於互斥訪問或同步,二值訊號量和互斥訊號量非常相似,但互斥訊號量有優先順序,二值訊號量沒有。因此二值訊號...

python訊號量 Python訊號量

python訊號量教程 訊號量是由作業系統管理的一種抽象資料型別,用於在多執行緒中同步對共享資源的使用。本質上說,訊號量是乙個內部資料,用於標明當前的共享資源可以有多少併發讀取。也可以簡單的理解為,訊號量是多把鎖,同時允許多個執行緒來更改資料,而 python訊號量與互斥鎖的關係 訊號量的乙個特殊用...

訊號 訊號量

訊號是由 系統或者程序傳送給目標程序的資訊,以通知目標程序某個狀態的改變或系統異常。linux訊號可以由如下條件產生 1 對於前台程序,使用者可以通過輸入特殊的終端字元來給它傳送訊號。比如輸入ctrl c通常或給程序傳送乙個中斷訊號 2 系統異常。比如浮點異常和非法記憶體段訪問。3 系統狀態變化 4...