|  | ||||||||||||||||||||||||||||||||||
| linux下的信號量 | ||||||||||||||||||||||||||||||||||
| 本文關鍵字: linux下的信號量,信號量編程 一、信號量概述 在多任(ren)務操作(zuo)系統環境下,多個進(jin)(jin)程(cheng)(cheng)會同時運(yun)行,并且一些進(jin)(jin)程(cheng)(cheng)間可能存在一定(ding)的關(guan)聯。多個進(jin)(jin)程(cheng)(cheng)可能為了(le)完成同一個任(ren)務相互協作(zuo),這就形成了(le)進(jin)(jin)程(cheng)(cheng)間的同步(bu)關(guan)系。而且在不(bu)同進(jin)(jin)程(cheng)(cheng)間,為了(le)爭奪(duo)有限的系統資源(yuan)(硬件或軟件資源(yuan))會進(jin)(jin)入競爭狀(zhuang)態,這就是進(jin)(jin)程(cheng)(cheng)間的互斥(chi)關(guan)系。 進程間的互(hu)斥關系與同步(bu)關系存在(zai)的根源(yuan)(yuan)在(zai)于臨(lin)界(jie)(jie)資(zi)(zi)源(yuan)(yuan)。臨(lin)界(jie)(jie)資(zi)(zi)源(yuan)(yuan)是在(zai)同一(yi)個(ge)(ge)時(shi)刻只允許有限(xian)個(ge)(ge)(通常只有一(yi)個(ge)(ge))進程可以訪問(wen)(讀)或修改(寫(xie))的資(zi)(zi)源(yuan)(yuan),通常包括硬(ying)件(jian)資(zi)(zi)源(yuan)(yuan)(處理器、內存、存儲(chu)器及(ji)其(qi)他外圍設備等(deng))和軟件(jian)資(zi)(zi)源(yuan)(yuan)(共(gong)享(xiang)代碼(ma)(ma)段、共(gong)享(xiang)結構和變量等(deng))。訪問(wen)臨(lin)界(jie)(jie)資(zi)(zi)源(yuan)(yuan)的代碼(ma)(ma)叫(jiao)做臨(lin)界(jie)(jie)區,臨(lin)界(jie)(jie)區本身也會(hui)成(cheng)為臨(lin)界(jie)(jie)資(zi)(zi)源(yuan)(yuan)。 信(xin)號量是用來解決進(jin)程間的(de)同步與互斥問題的(de)一(yi)種進(jin)程間通(tong)信(xin)機制,包括一(yi)個稱為信(xin)號量的(de)變量和(he)在該(gai)信(xin)號量下等(deng)待(dai)資(zi)(zi)源的(de)進(jin)程等(deng)待(dai)隊(dui)列(lie),以(yi)及對(dui)信(xin)號量進(jin)行的(de)兩個原(yuan)子操作(zuo)(PV操作(zuo))。其中(zhong)信(xin)號量對(dui)應于某一(yi)種資(zi)(zi)源,取一(yi)個非(fei)負(fu)的(de)整(zheng)型(xing)值(zhi)。信(xin)號量值(zhi)指的(de)是當前(qian)可(ke)用的(de)該(gai)資(zi)(zi)源的(de)數量,若等(deng)于0則(ze)意(yi)味著目(mu)前(qian)沒有可(ke)用的(de)資(zi)(zi)源。 PV原子操作的具體定義(yi)如下。 ● P操作:如果(guo)有(you)(you)可用的資(zi)源(yuan)(信號(hao)量值(zhi)>0),則(ze)占用一個資(zi)源(yuan)(給信號(hao)量值(zhi)減1,進(jin)(jin)入臨(lin)界(jie)區代碼);如果(guo)沒有(you)(you)可用的資(zi)源(yuan)(信號(hao)量值(zhi)=0),則(ze)被阻塞直(zhi)(zhi)到(dao)系(xi)統將(jiang)資(zi)源(yuan)分配給該進(jin)(jin)程(進(jin)(jin)入等待隊(dui)列,一直(zhi)(zhi)等到(dao)資(zi)源(yuan)輪到(dao)該進(jin)(jin)程)。 ● V操作:如果在該(gai)信(xin)號(hao)量的(de)等(deng)待隊列中有(you)進程(cheng)在等(deng)待資(zi)源(yuan),則喚醒一(yi)個阻塞進程(cheng);如果沒有(you)進程(cheng)等(deng)待它,則釋放一(yi)個資(zi)源(yuan)(給信(xin)號(hao)量值加1)。 常見的使用信號量(liang)訪問臨界區的偽(wei)代碼如下(xia):     { 簡(jian)單的信(xin)號(hao)量(liang)只(zhi)能取(qu)0和(he)1兩種(zhong)值,這種(zhong)信(xin)號(hao)量(liang)叫做二維(wei)(wei)信(xin)號(hao)量(liang)。在本節中(zhong),主要討論二維(wei)(wei)信(xin)號(hao)量(liang)。二維(wei)(wei)信(xin)號(hao)量(liang)的應用比較容(rong)易擴展到使用多維(wei)(wei)信(xin)號(hao)量(liang)的情(qing)況(kuang)。 二、信號量編程 1.函數說(shuo)明 在Linux系統中,使用信號(hao)量(liang)通常分(fen)為以(yi)下幾個步(bu)驟(zou): (1)創建信(xin)(xin)號(hao)(hao)量或獲得在(zai)系(xi)統(tong)中已(yi)存在(zai)的信(xin)(xin)號(hao)(hao)量,此(ci)時需要調用(yong)semget()函數(shu)。不同(tong)進程(cheng)通(tong)過(guo)使用(yong)同(tong)一個信(xin)(xin)號(hao)(hao)量鍵(jian)值來獲得同(tong)一個信(xin)(xin)號(hao)(hao)量。 (2)初始(shi)化信(xin)(xin)號量,此時使用semctl()函數(shu)的SETVAL操作。當(dang)使用二維信(xin)(xin)號量時,通常(chang)將信(xin)(xin)號量初始(shi)化為1。 (3)進行信號量的(de)PV操作,此(ci)時調(diao)用semop()函數(shu)。這一步是實現進程間(jian)的(de)同步和互斥(chi)的(de)核(he)心工作部分。 (4)如果不需要信(xin)號量,則從(cong)系統中刪(shan)除(chu)它,此時使用(yong)semctl ()函數的(de)(de)IPC_RMID操作(zuo)(zuo)。需要注意的(de)(de)是,在程序中不應該出現對已經(jing)被刪(shan)除(chu)的(de)(de)信(xin)號量的(de)(de)操作(zuo)(zuo)。 2.函數格(ge)式  表1列舉了semget()函(han)數的語法要(yao)點。 表(biao)1 semget()函數語法要點(dian) 
 表2列舉了semctl()函數的語法要點。 表2 semctl()函數語法要點 
  表3列舉了(le)semop()函(han)數的語法要點。 表3 semop()函(han)數語法要點 
 因為信號量(liang)相關(guan)的(de)函(han)(han)數(shu)(shu)調用(yong)接口比(bi)較復雜(za),我們可(ke)以(yi)將它們封裝成(cheng)二維單個信號量(liang)的(de)幾個基本函(han)(han)數(shu)(shu),分別(bie)為信號量(liang)初始(shi)化函(han)(han)數(shu)(shu)(或者信號量(liang)賦值函(han)(han)數(shu)(shu))init_sem()、P操作(zuo)函(han)(han)數(shu)(shu)sem_p()、V操作(zuo)函(han)(han)數(shu)(shu)sem_v()及(ji)刪除信號量(liang)函(han)(han)數(shu)(shu)del_sem()等,具體(ti)實現(xian)如下(xia):     /* sem_com.c */ 以(yi)下實(shi)例(li)說明了信號(hao)量(liang)的概念及基本用法。在實(shi)例(li)程序(xu)中,首先創(chuang)建一個子進程,然后(hou)使用信號(hao)量(liang)來控制(zhi)兩個進程(父子進程)間的執行順序(xu)。     /* fork.c */ 讀者可以先從該程序(xu)中(zhong)刪除信號量相關的代(dai)碼部(bu)分(fen)并觀(guan)察運(yun)行結果。     $ ./simple_fork   再添加信號量(liang)的控制(zhi)部分(fen)并(bing)運行結果。     $ ./sem_fork 本實例說明了使用信號(hao)量(liang)怎么解決多進程間存在(zai)的(de)同步問題。我們將在(zai)后面講述的(de)共享(xiang)內(nei)存和消息(xi)隊列的(de)實例中,看(kan)到(dao)使用信號(hao)量(liang)實現多進程之間的(de)互斥。 本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發》 熱點鏈接: 
         1、linux下的信號處理實例 |