三、demo 父子程序的訊號量
在對於臨界區資源管理的過程中,多個程式同時訪問乙個共享資源經常容易引發一系列問題:如死鎖,結果不唯一等等,使用訊號量,來解決程序或執行緒間共享資源引發的同步問題。
讓多個程序通過特殊變數展開互動,乙個程序在某乙個關鍵點上被迫停止執行直至接收到對應的特殊變數值,通過這一措施,任何複雜的程序互動要求均可得到滿足,這種特殊的變數就是訊號量。特點它是乙個特殊變數,訪問具有原子性。,只允許對它進行等待和傳送訊號這兩種操作。
1)等待訊號量(p)
當訊號量值為0時,程式等待;當訊號量值大於0時,訊號量減1,程式繼續執行。
2)傳送訊號量(v)
將訊號量值加1。
工作原理
舉個例子,就是兩個程序共享訊號量sv,一旦其中乙個程序執行了p(sv)操作,它將得到訊號量,並可以進入臨界區,使sv減1。而第二個程序將被阻止進入臨界區,因為當它試圖執行p(sv)時,sv為0,它會被掛起以等待第乙個程序離開臨界區域並執行v(sv)釋放訊號量,這時第二個程序就可以恢復執行。
由於訊號量只能進行兩種操作等待和傳送訊號,即p(sv)和v(sv),他們的行為是這樣的:
#include
int semget(key_t key, int num_sems, int sem_flags);
引數:key是整數值(唯一非零),就是linux執行緒操作中經常用到的鍵值,可以通過ftok函式得到,不相關的程序可以通過它訪問乙個訊號量,它代表程式可能要使用的某個資源,程式對所有訊號量的訪問都是間接的,程式先通過呼叫semget函式並提供乙個鍵,再由系統生成乙個相應的訊號識別符號(semget函式的返回值),只有semget函式才直接使用訊號量鍵,所有其他的訊號量函式使用由semget函式返回的訊號量識別符號。如果多個程式使用相同的key值,key將負責協調工作。
num_sems:指定需要的訊號量數目
當semget建立新的訊號量集合時,必須指定集合中訊號量的個數(即num_sems),通常為1; 如果是引用乙個現有的集合,則將num_sems指定為 0 。
sem_flags是一組標誌,當想要當訊號量不存在時建立乙個新的訊號量,可以和值ipc_creat做按位或操作。設定了ipc_creat標誌後,即使給出的鍵是乙個已有訊號量的鍵,也不會產生錯誤。而ipc_creat | ipc_excl則可以建立乙個新的,唯一的訊號量,如果訊號量已存在,返回乙個錯誤。
返回值:semget函式成功返回乙個相應訊號識別符號(非零),失敗返回-1
int semop(int semid, struct sembuf *sops, size_t numops);
該函式的作用是改變訊號量的值,其實就是為了訊號量的pv操作而準備的
通過判斷其返回值,檢視訊號量集的情況
引數:semid:訊號量集的識別符號
sembuf:結構體格式如下 結構體指標(引數注意&)
numops:指出將要進行操作的訊號的個數
struct sembuf
;
結構體中的sem_op 引數:
結構體中的sem_*** 引數:
該引數可設定為 ipc_nowait 或 sem_undo 兩種狀態,通常為sem_undo
int semctl(int sem_id,int sem_num,int command,[union semun sem_union]);
semid:訊號量集的識別符號;
sem_num:即將要進行操作的訊號量的編號,即訊號量集合的索引值,其中第乙個訊號量的索引值為0。
command:將要在集合上執行的命令,通常用特定的巨集代替:
常用的巨集有;
semun:是乙個聯合體
一般用到val,表示要傳給訊號量的初始值
union semun
;
父子程序的執行順序是先父程序執行,再子程序執行。利用訊號量控制,達到子程序先執行的目的
#include
#include
#include
#include
//聯合型別semun定義
union semun
;// v操作:
// 釋放資源並將訊號量值+1
// 如果有程序正在掛起等待,則喚醒它們
void
vbackkey
(int id)
// p操作:
// 若訊號量值為1,獲取資源並將訊號量值-1
// 若訊號量值為0,程序掛起等待
void
pgetkey
(int id)
intmain
(int argc,
char
**ar**)
else
if(pid ==0)
//子程序
別人的**demo
#include
#include
#include
#include
#include
//包含訊號量定義的標頭檔案
//聯合型別semun定義
union semun
;//函式宣告
//函式:設定訊號量的值
static
intset_semvalue
(void);
//函式:刪除訊號量
static
void
del_semvalue
(void);
//函式:訊號量p操作
static
intsemaphore_p
(void);
//函式:訊號量v操作
static
intsemaphore_v
(void);
static
int sem_id;
//訊號量id
intmain
(int argc,
char
*ar**)
op_char =
'x';
//對程序進行標記
sleep(5
);}//迴圈:訪問臨界區
for( i =
0; i <10;
++i )
printf
("\n %d - finished \n"
,getpid()
);if( argc >1)
return0;
}//函式:設定訊號量的值
static
intset_semvalue
(void
)//函式:刪除訊號量
static
void
del_semvalue
(void
)//函式:訊號量p操作:對訊號量進行減一操作
static
intsemaphore_p
(void
)return1;
}//函式:訊號量v操作:對訊號量進行加一操作
程序間通訊IPC 訊號
訊號 訊號是程序間唯一的非同步通訊 1 由硬體檢測產生 sigsegv 段錯誤 2 由終端按鍵產生 sigint ctrl c 3 由軟體本身產生 sigpipe 管道 4 由核心傳送 sigio sigurg 5 由其他程序傳送 kill 收到乙個訊號該怎麼處理 1 忽略該訊號 2 按照預設方式處...
程序間通訊(IPC) 訊號
關於訊號的常用命令 kill l 檢視系統中所有的訊號 需要的標頭檔案 include include 引數原型 int kill pid t pid,int sig pid 要傳送訊息的程序號 sig 訊號 例如 kill pid,signum 返回值 成功返回0 失敗返回 1 需要的標頭檔案 i...
Linux程序間通訊 IPC 訊號量
訊號量是作業系統中線程 程序間訪問臨界資源的同步方式。其有兩個關鍵操作 p 申請臨界資源,申請成功那麼訊號量 1 v 釋放臨界資源,釋放成功那麼訊號量 1 system v ipc資源包含共享記憶體 訊息佇列 以及訊號量。其關鍵函式如下 int semget key t key,int num se...