IPC物件之訊號量

2021-08-20 05:41:07 字數 4480 閱讀 9270

1. 訊號量

1)訊號量(semaphore),也叫訊號燈。它是不同程序間或乙個給定程序內部不同執行緒間同步的機制。

2)二值訊號量:值為0或1。與互斥鎖類似,資源可用時值為1,不可用時值為0。

3)計數訊號量:值在0到n之間。同來統計資源,其值代表可用資源數。

4)等待操作是等待訊號量的值變為大於0,然後將其減一;而釋放操作則相反,用來喚醒等待資源的程序或者執行緒。

2. 訊號量程式設計函式

在linux系統中,使用訊號量通常需要建立訊號量、初始化訊號量、訊號量pv操作以及訊號量刪除四種操作。

1)建立訊號量

函式semget()

所需標頭檔案:#include

#include

#include

函式原型:int semget(key_t key, int nsems, intsem***)

函式引數:

key         訊號量的鍵值,其他程序通過該值訪問該訊號量,其中有個特殊值ipc_private,表示建立當前程序的私有訊號量

nsems    需要建立的訊號量數目,通常為1。若建立多個訊號量則稱為訊號量集

sem***    同open()函式的第三個引數,為訊號量設定許可權,通常使用八進位制表示。

函式返回值:

成功:訊號量的識別符號(非負整數)

失敗:-1

2)初始化訊號量,函式semctl()用於對訊號量進行相應的控制,包括設定初始化值、獲取資訊、設定屬性、刪除訊號量(集)等操作

函式semctl()

標頭檔案:#include

#include

#include

函式原型:int semctl(int semid, int semnum, intcmd, union semun arg)

函式引數:

semid     訊號量識別符號(即semget()函式的返回值)

semnum 訊號量編號,通常存在多個訊號量時才會使用。通常取值為0,即第乙個訊號量。

cmd       需要對訊號量採取的操作。可取值有很多,常用的有:

ipc_stat       讀取訊息佇列的資料結構semid_ds並將其儲存在第四個引數arg結構變數的buf指定的位址中

ipc_setval   將訊號量值設定為arg中的val值

ipc_getval   獲取當前訊號量的值

ipc_rmid      從核心中刪除訊號量(集)

arg         是乙個union semun結構的共用體,常用型別如下:

union semun

int              val;    /* value for setval */

struct semid_ds *buf;    /* buffer for ipc_stat,ipc_set */

unsigned short  *array;  /* array for getall, setall */

struct seminfo  *__buf;  /* buffer for ipc_info

(linux-specific) */

注意:某些系統內未給出union semun的定義,需要程式設計師自己定義該共用體。

struct  semid_ds

uid_t sem_perm.uid;    /* effective uid of owner*/

gid_t sem_perm.gid;    /* effective gid of owner*/

函式返回值:成功:

ipc_stat、ipc_setval或ipc_rmid操作:0

ipc_getval操作:返回當前訊號量的值

失敗:-1

3)訊號量pv操作

函式semop()

標頭檔案:#include

#include

#include

函式原型:int semop(int semid, struct sembuf*sops, size_t nsops)

函式引數:

semid     訊號量識別符號(即semget()函式的返回值)

struct sembuf

unsigned short sem_num;//訊號量編號,若是單個訊號量則取值0

short sem_op;//取值-1為p操作,取值1為v操作

short sem_***;//通常取值sem_undo,表示程序結束後系統自動釋放該程序中未釋放的訊號量

nsops     需要操作的訊號量數目,通常取值1(乙個操作)

函式返回值:

成功:訊號量的識別符號

失敗:-1

示例:有兩個程序,程序a和程序b,這兩個程序通過共享記憶體通訊,程序a負責寫記憶體,程序b負責讀記憶體。要求程序a寫一次,然後b讀一次。這裡用兩個訊號量進行讀寫的同步。(在博文:ipc物件之共享記憶體中使用無名管道進行都寫得同步)。

方法一程式結構圖如下:

示例**:

@author: wanghao

@created time : wed 23 may 2018 07:37:06 pmpdt

@file name: sem_demo.c

@description:

#include

#include

#include

#include

#include

#include

/*the structure that stores the data*/

typedef structstorage;

void init(storage *s)

assert(s!= null);

/*create semaphore, return semaphore value*/

if((s->semid= semget(ipc_private,2,ipc_creat|ipc_excl|0777)) <0);

un.array= array;

/*set all values in the semaphore*/

if(semctl(s->semid,0,setall,un)<0)};

/*set semaphore 1 to p operation*/

struct sembuf ops_p[1] = };

/*set semaphore 1 to p operation*/

if(semop(s->semid,ops_p,1)<0)};    

/*set semaphore 0 to v operation*/

struct sembuf ops_v[1] = };

/*set semaphore 0 to p operation*/

if(semop(s->semid,ops_p,1)<0)else if(pid > 0)elsestorage;

void init(storage *s)

assert(s!= null);

/*createsemaphore, return semaphore value*/

if((s->semid= semget(ipc_private,2,ipc_creat|ipc_excl|0777)) <0);

un.array= array;

/*setall values in the semaphore*/

if(semctl(s->semid,0,setall,un)<0)};

/*set semaphore 1 to p operation*/

struct sembuf ops_p[1] = };

s->val = val;

printf("%d write %d\n",getpid(),val);

/*set semaphore 1 to v operation*/

if(semop(s->semid,ops_v,1) <0)

/*set semaphore 1 to p operation*/

if(semop(s->semid,ops_p,1)<0)

void read(storage *s)

assert(s!= null);

/*setsemaphore 0 to p operation*/

structsembuf ops_p[1] = };

/*setsemaphore 0 to v operation*/

structsembuf ops_v[1] = };

/*setsemaphore 0 to p operation*/

if(semop(s->semid,ops_p,1)<0)elseif(pid > 0)else{

inti = 1;

for(;i<=100;i++){

read(s);

/*unlocka shared memory map*/

shmdt(s);

exit(0);

IPC之 訊號量集 多個訊號量

如果兩個程序不僅需要同步,還要保證先後執行順序,就要用兩個訊號量 互斥鎖 來解決 柵欄模型 實現以下框架中的四個子程序 所有程序做完任務後 在一起執行下一次 include include include include include include include include define ...

IPC 訊號量集

ipc通訊機制 訊號量集 1.int semget key t key,int nsems,int sem 第乙個引數是由ftok 獲取的key 第二個引數是要建立的訊號量的個數,如果是0表示獲取訊號量集id 第三個引數是ipc creat,建立訊號量集id。返回乙個訊號量集的id semid.se...

Linux學習筆記之IPC 物件之訊號量集

目的 配合共享記憶體完成程序間通訊 使用框架 key 申請訊號量集 pv操作 解除安裝刪除訊號量集 semget semop semctl 1 申請訊號量 include int semget key t key,int nsems,int sem 功能 該函式可以使用特定的key向核心提出訊號量集...