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