Linux操作系統(tǒng)的信號(hào)量詳細(xì)解釋
Linux操作系統(tǒng)的信號(hào)量詳細(xì)解釋
Linux操作系統(tǒng)信號(hào)量是進(jìn)程間通信的方法之一。下面由學(xué)習(xí)啦小編為大家整理了Linux操作系統(tǒng)的信號(hào)量詳細(xì)解釋的相關(guān)知識(shí),希望對(duì)大家有幫助!
Linux操作系統(tǒng)的信號(hào)量詳細(xì)解釋一、什么是信號(hào)量
為了防止出現(xiàn)因多個(gè)程序同時(shí)訪問(wèn)一個(gè)共享資源而引發(fā)的一系列問(wèn)題,我們需要一種方法,它可以通過(guò)生成并使用令牌來(lái)授權(quán),在任一時(shí)刻只能有一個(gè)執(zhí)行線程訪問(wèn)代碼的臨界區(qū)域。臨界區(qū)域是指執(zhí)行數(shù)據(jù)更新的代碼需要獨(dú)占式地執(zhí)行。而信號(hào)量就可以提供這樣的一種訪問(wèn)機(jī)制,讓一個(gè)臨界區(qū)同一時(shí)間只有一個(gè)線程在訪問(wèn)它,也就是說(shuō)信號(hào)量是用來(lái)調(diào)協(xié)進(jìn)程對(duì)共享資源的訪問(wèn)的。
信號(hào)量是一個(gè)特殊的變量,程序?qū)ζ湓L問(wèn)都是原子操作,且只允許對(duì)它進(jìn)行等待(即P(信號(hào)變量))和發(fā)送(即V(信號(hào)變量))信息操作。最簡(jiǎn)單的信號(hào)量是只能取0和1的變量,這也是信號(hào)量最常見(jiàn)的一種形式,叫做二進(jìn)制信號(hào)量。而可以取多個(gè)正整數(shù)的信號(hào)量被稱為通用信號(hào)量。這里主要討論二進(jìn)制信號(hào)量。
Linux操作系統(tǒng)的信號(hào)量詳細(xì)解釋二、信號(hào)量的工作原理
由于信號(hào)量只能進(jìn)行兩種操作等待和發(fā)送信號(hào),即P(sv)和V(sv),他們的行為是這樣的:
P(sv):如果sv的值大于零,就給它減1;如果它的值為零,就掛起該進(jìn)程的執(zhí)行
V(sv):如果有其他進(jìn)程因等待sv而被掛起,就讓它恢復(fù)運(yùn)行,如果沒(méi)有進(jìn)程因等待sv而掛起,就給它加1.
舉個(gè)例子,就是兩個(gè)進(jìn)程共享信號(hào)量sv,一旦其中一個(gè)進(jìn)程執(zhí)行了P(sv)操作,它將得到信號(hào)量,并可以進(jìn)入臨界區(qū),使sv減1。而第二個(gè)進(jìn)程將被阻止進(jìn)入臨界區(qū),因?yàn)楫?dāng)它試圖執(zhí)行P(sv)時(shí),sv為0,它會(huì)被掛起以等待第一個(gè)進(jìn)程離開臨界區(qū)域并執(zhí)行V(sv)釋放信號(hào)量,這時(shí)第二個(gè)進(jìn)程就可以恢復(fù)執(zhí)行。
Linux操作系統(tǒng)的信號(hào)量詳細(xì)解釋三、Linux的信號(hào)量機(jī)制
Linux提供了一組精心設(shè)計(jì)的信號(hào)量接口來(lái)對(duì)信號(hào)進(jìn)行操作,它們不只是針對(duì)二進(jìn)制信號(hào)量,下面將會(huì)對(duì)這些函數(shù)進(jìn)行介紹,但請(qǐng)注意,這些函數(shù)都是用來(lái)對(duì)成組的信號(hào)量值進(jìn)行操作的。它們聲明在頭文件sys/sem.h中。
1、semget函數(shù)
它的作用是創(chuàng)建一個(gè)新信號(hào)量或取得一個(gè)已有信號(hào)量,原型為:
[cpp] view plain copy print?
int semget(key_t key, int num_sems, int sem_flags);
第一個(gè)參數(shù)key是整數(shù)值(唯一非零),不相關(guān)的進(jìn)程可以通過(guò)它訪問(wèn)一個(gè)信號(hào)量,它代表程序可能要使用的某個(gè)資源,程序?qū)λ行盘?hào)量的訪問(wèn)都是間接的,程序先通過(guò)調(diào)用semget函數(shù)并提供一個(gè)鍵,再由系統(tǒng)生成一個(gè)相應(yīng)的信號(hào)標(biāo)識(shí)符(semget函數(shù)的返回值),只有semget函數(shù)才直接使用信號(hào)量鍵,所有其他的信號(hào)量函數(shù)使用由semget函數(shù)返回的信號(hào)量標(biāo)識(shí)符。如果多個(gè)程序使用相同的key值,key將負(fù)責(zé)協(xié)調(diào)工作。
第二個(gè)參數(shù)num_sems指定需要的信號(hào)量數(shù)目,它的值幾乎總是1。
第三個(gè)參數(shù)sem_flags是一組標(biāo)志,當(dāng)想要當(dāng)信號(hào)量不存在時(shí)創(chuàng)建一個(gè)新的信號(hào)量,可以和值IPC_CREAT做按位或操作。設(shè)置了IPC_CREAT標(biāo)志后,即使給出的鍵是一個(gè)已有信號(hào)量的鍵,也不會(huì)產(chǎn)生錯(cuò)誤。而IPC_CREAT | IPC_EXCL則可以創(chuàng)建一個(gè)新的,唯一的信號(hào)量,如果信號(hào)量已存在,返回一個(gè)錯(cuò)誤。
semget函數(shù)成功返回一個(gè)相應(yīng)信號(hào)標(biāo)識(shí)符(非零),失敗返回-1.
2、semop函數(shù)
它的作用是改變信號(hào)量的值,原型為:
[cpp] view plain copy print?
int semop(int sem_id, struct sembuf *sem_opa, size_t num_sem_ops);
sem_id是由semget返回的信號(hào)量標(biāo)識(shí)符,sembuf結(jié)構(gòu)的定義如下:
[cpp] view plain copy print?
struct sembuf{
short sem_num;//除非使用一組信號(hào)量,否則它為0
short sem_op;//信號(hào)量在一次操作中需要改變的數(shù)據(jù),通常是兩個(gè)數(shù),一個(gè)是-1,即P(等待)操作,
//一個(gè)是+1,即V(發(fā)送信號(hào))操作。
short sem_flg;//通常為SEM_UNDO,使操作系統(tǒng)跟蹤信號(hào),
//并在進(jìn)程沒(méi)有釋放該信號(hào)量而終止時(shí),操作系統(tǒng)釋放信號(hào)量
};
3、semctl函數(shù)
該函數(shù)用來(lái)直接控制信號(hào)量信息,它的原型為:
[cpp] view plain copy print?
int semctl(int sem_id, int sem_num, int command, ...);
如果有第四個(gè)參數(shù),它通常是一個(gè)union semum結(jié)構(gòu),定義如下:
[cpp] view plain copy print?
union semun{
int val;
struct semid_ds *buf;
unsigned short *arry;
};
前兩個(gè)參數(shù)與前面一個(gè)函數(shù)中的一樣,command通常是下面兩個(gè)值中的其中一個(gè)
SETVAL:用來(lái)把信號(hào)量初始化為一個(gè)已知的值。p 這個(gè)值通過(guò)union semun中的val成員設(shè)置,其作用是在信號(hào)量第一次使用前對(duì)它進(jìn)行設(shè)置。
IPC_RMID:用于刪除一個(gè)已經(jīng)無(wú)需繼續(xù)使用的信號(hào)量標(biāo)識(shí)符。