Linux程序間通訊 訊號量

2021-10-04 05:01:54 字數 2946 閱讀 5749

訊號量是os建立的共享變數,程序在進行操作之前會先檢查這個變數的值,以實現互斥。

訊號量的使用主要是用來保護共享資源,使得資源在乙個時刻只有乙個程序所擁有。

linux提供兩種訊號量:

(1)核心訊號量,由核心控制使用

(2)使用者態程序使用的訊號量,這種訊號量又分為posix訊號量和system v訊號量。posix訊號量又分為有名訊號量(其值儲存在檔案中,所以他可以用於執行緒也可以用於程序間的同步)和無名訊號量(其值無法儲存在記憶體中)。

posix訊號量和system v訊號量的比較

(1)對posix來說,訊號量是個非負整數。或用於執行緒間同步。而system v訊號量則是乙個或多個訊號量的集合,它對應的是乙個訊號量結構體,這個結構體是為system v ipc服務的,訊號量只不過是他的一部分。常用於程序間同步。

(2)posix訊號量的引用標頭檔案是,而system v訊號量的標頭檔案是

system v訊號量

訊號量的值為正的時候,說明它空閒。所測試的執行緒可以鎖定而使用它。若為0,說明它被占用,測試的程序要進入睡眠佇列中等待被喚醒

程序呼叫semget函式建立新的訊號量集合,或者獲取已建立的訊號量集合

函式定義:int semget(key_t key,int num_sems,int sem_flags);

第乙個引數——key_t key,通過ftok函式得到的鍵值,不相關的程序可以通過它訪問同乙個訊號量。

第二個引數——nsems,代表訊號量的個數,如果只是訪問而不建立則可以指定該引數為0,一旦建立了訊號量,就不能改變其訊號量的個數。只要不刪除該訊號量,重新呼叫semget函式建立該鍵值得訊號量,函式只是返回以前建立的值,不會重新建立,通常情況下為1。

第三個引數——oflag,指定該訊號量的讀寫許可權,若指定ipc_creat,與key關聯的訊號量集不存在則建立。

返回值——成功則返回相應的訊號量識別符號,失敗則返回-1。

呼叫semctl函式給集合中的每乙個訊號量設定初始值。

函式定義:int semctl(int sem_id, int sem_num, int command, [union semun sem_union]);

第乙個引數——sem_id,訊號量識別符號;

第二個引數——sem_num,訊號量的值,一般取值為0;

第三個引數——command,通常是下面兩個值中的其中乙個

(1)setval:用來把訊號量初始化為乙個已知的值。

(2)ipc_rmid:用於刪除乙個訊號量識別符號。

第四個引數——sem_union,可選引數,是乙個union semun結構,一般表示要傳給訊號量的初始值.

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

呼叫semop函式,對集合中的訊號量進行pv操作

(p加鎖:對訊號量-1,如果訊號量的值為0,p操作會阻塞;v解鎖:對訊號量+1,v操作不會出現阻塞)

函式定義:int semop(int sem_id, struct sembuf *sem_opa, size_t num_sem_ops);

第乙個引數——semid,表示semget返回的訊號量識別符號;

第二個引數——semopa,表示乙個由sembuf結構表示的訊號量運算元組;

第三個引數——num_sem_ops,規定該陣列中運算元的數量

返回值——成功返回0,失敗返回-1;

sembuf(訊號量運算元組)

struct buf
#include

#include

#include

#include

#include

#include

#include

typedef

struct

sm;#define shm_key 1

#define sem_key 2

intmain()

sm =

shmat

(shmid,

null,0

);//程序將共享記憶體繫結到自己的空間中,返回位址

if(sm==

(void*)

-1)int semid =

semget

(sem_key,1,

0644

|ipc_creat)

;//建立乙個訊號量集合,返回值為sem_key值

if(semid==-1

)semctl

(semid,

0,setval,1)

;//給集合中的每乙個訊號量賦初始值

pid_t pid=

fork()

;if(pid <0)

if(pid ==0)

memset

(sm,0,

sizeof

(sm));

} sb.sem_op=1;

//v ulock

semop

(semid,

&sb,1)

;usleep

(100);

}if(semctl

(semid,ipc_rmid,

null)==

-1)if

(shmdt

(sm)==(

void*)

-1)if

(shmctl

(shmid,ipc_rmid,

null)==

-1)}

else

if(pid >0)

sb.sem_op=1;

//vsemop

(semid,

&sb,1)

;usleep

(100);

}if(shmdt

(sm)==(

void*)

-1)sleep(3

);}return0;

}

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 程序間通訊 訊號量

linux學習目錄 1 什麼是訊號量?在對於臨界區資源管理過程中,為了防止多個程式同時訪問乙個共享資源而引發的一系列問題。比如 死鎖。為了解決這種問題,巨人們就發明了訊號量。訊號量就是為了解決在乙個臨界區只有乙個程序訪問它,也就是說訊號量相當於交警,來協調程序對共享資源有序的訪問而不造成死鎖等行為。...