 信號量是什么(me),大(da)神(shen)全方位交給你
							時(shi)間:2018-04-19      來源:未(wei)知
							信號量是什么(me),大(da)神(shen)全方位交給你
							時(shi)間:2018-04-19      來源:未(wei)知 
							一.首先我們必(bi)須知道什(shen)么(me)是信號量
信號量的本質是數據(ju)操作鎖,它本身不(bu)具備數據(ju)交換功能,而(er)只是用于保護(hu)進程(cheng)線程(cheng)之間共享的資源(yuan),實現對(dui)共享資源(yuan)的同步與互斥操作。
信(xin)號量相(xiang)當(dang)(dang)于一把鎖,例如小(xiao)黑上廁(ce)所,需要檢查是(shi)否(fou)有(you)鎖,有(you)鎖獲取(qu)鎖,占(zhan)用(yong)廁(ce)所坑(keng)位資源,其他人無法進此坑(keng)位,當(dang)(dang)小(xiao)黑上完廁(ce)所,需要釋放鎖,其他人都(dou)可以獲取(qu)鎖。
小黑 ------》 進(jin)程
門鎖 --------》 信號(hao)量
坑位 ------》 共享資源(信號量保(bao)護對象)
二(er).為什么要使用(yong)信號量
為了防止出現因多個程(cheng)序同時(shi)(shi)訪問(wen)一(yi)個共享(xiang)資(zi)源而(er)引(yin)發(fa)的(de)(de)一(yi)系列問(wen)題(ti),我們需要一(yi)種(zhong)方法,在(zai)(zai)任一(yi)時(shi)(shi)刻只能有一(yi)個執行進(jin)程(cheng)訪問(wen)代碼(ma)的(de)(de)臨界區域(yu);臨界區域(yu)是(shi)指執行數據更新的(de)(de)代碼(ma)需獨(du)占式地執行。而(er)信號量(liang)就(jiu)(jiu)可以(yi)提供(gong)這樣的(de)(de)一(yi)種(zhong)訪問(wen)機制(zhi),讓(rang)一(yi)個臨界區同一(yi)時(shi)(shi)間(jian)只有一(yi)個進(jin)程(cheng)在(zai)(zai)訪問(wen)它,也就(jiu)(jiu)是(shi)說信號量(liang)是(shi)用來調協進(jin)程(cheng)對共享(xiang)資(zi)源的(de)(de)訪問(wen)的(de)(de)。其(qi)中共享(xiang)內存(cun)的(de)(de)使用就(jiu)(jiu)要用到信號量(liang)。
臨界資源:一次只允許一個進程(一個線程)使用的資源叫做(zuo)臨界資源。
臨(lin)界區:訪問臨(lin)界資源的代碼稱(cheng)為臨(lin)界區。
三.信號量分類:
1.System V信號燈(IPC對(dui)象),也(ye)叫經典ipc對(dui)象,一般(ban)用(yong)于進(jin)程(cheng)通信。
2.posix基于(yu)內存(cun)的信(xin)號燈(無名信(xin)號燈),一般線程通信(xin)。
功能分類:
1.二值(zhi)信號量:信號量的值(zhi)為0或1。與互斥鎖類似(si),資源可用時值(zhi)為1,不可用時值(zhi)為0。
2.計數信號量:值在0到n之(zhi)間。用來統計資源,其值代表可用資源數。
注意(yi):system v信(xin)號量對象不是一(yi)個(ge)(ge)(ge)信(xin)號量,是一(yi)個(ge)(ge)(ge)或者多個(ge)(ge)(ge)信(xin)號量的集合。對應內核中一(yi)個(ge)(ge)(ge)結(jie)構體:struct semid_ds 有(you)一(yi)個(ge)(ge)(ge)成員sem_base指向(xiang)第(di)0個(ge)(ge)(ge)信(xin)號量結(jie)構體起始地址(zhi)。
 
四(si).System v信號量實現步驟
-----》1、創建信(xin)號量(liang)對象
int semget(key_t key, int nsems, int semflg);
Key:創建(jian)信號(hao)量對象的唯一鍵值
nsems表示的(de)就是創建的(de)信號量集中信號量的(de)個數(shu)
Semflg: 權限(xian) IPC_CREAT:存在則(ze)打開(kai),否則(ze)創建; IPC_CREAT | IPC_EXCL存在則(ze)出錯返回(hui),否則(ze)創建,這(zhe) 樣保證(zheng)了(le) 打開(kai)的(de)是一個全新的(de)信號量集
成功:信號量集ID 失敗-1
----》2.初始化(hua)具體信(xin)號量的(de)值。
int semctl(int semid, int semnum, int cmd, union set);
semid:信號燈集ID
semnum: 要(yao)修(xiu)改的信號(hao)燈編號(hao)
Cmd: GETVAL:獲取信號燈的值
SETVAL:設置信號(hao)燈的(de)值
IPC_RMID:從系(xi)統中(zhong)刪除信號燈集(ji)合
-----》3.執行p操(cao)作(zuo):獲取資(zi)(zi)源(yuan),信號(hao)(hao)量值減1不阻(zu)塞(sai),可以操(cao)作(zuo)資(zi)(zi)源(yuan);如(ru)果無資(zi)(zi)源(yuan)可用,信號(hao)(hao)量值為0,阻(zu)塞(sai)等待資(zi)(zi)源(yuan)。
int semop(int semid, struct sembuf *sops, unsigned nsops);
semid:信號量集ID
struct sembuf {
short sem_num; // 要操作的信號燈的編號
short sem_op; // 0 : 等待,直(zhi)到信號燈的值變成0
// 1 : 釋放資(zi)源,V操作(zuo)
// -1 : 分配資源,P操(cao)作(zuo)
short sem_flg; // 0, IPC_NOWAIT, SEM_UNDO
};
nops: 要操作的(de)信號燈的(de)個數
----》 操作資源: 共享(xiang)內存
-----》4.執行(xing)v操(cao)作:釋放資源,信(xin)號(hao)量值加(jia)1.
int semop(int semid, struct sembuf *sops, unsigned nsops);
-----》5.刪除對(dui)象
int semctl(int semid, int semnum, int cmd, ...);