久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

Hi,歡迎來到嵌入式培訓高端品牌 - 華清遠見教育科技集團<北京總部官網>,專注嵌入式工程師培養15年!
當前位置: > 華清遠見教育科技集團 > 嵌入式學習 > 講師博文 > linux下的進程通信
linux下的進程通信
時間:2016-12-29作者:華清遠見

linux下的(de)進程(cheng)(cheng)(cheng)(cheng)通(tong)(tong)信手段(duan)基(ji)(ji)本上是從Unix平(ping)臺上的(de)進程(cheng)(cheng)(cheng)(cheng)通(tong)(tong)信手段(duan)繼承而來的(de)。而對(dui)Unix發(fa)(fa)展做出重大(da)貢(gong)獻的(de)兩大(da)主力AT&T的(de)貝爾(er)實驗室及BSD(加州大(da)學伯克利分校的(de)伯克利軟件發(fa)(fa)布中心)在(zai)進程(cheng)(cheng)(cheng)(cheng)間(jian)通(tong)(tong)信方(fang)面的(de)側重點(dian)有所不同。前(qian)者(zhe)對(dui)Unix早期(qi)的(de)進程(cheng)(cheng)(cheng)(cheng)間(jian)通(tong)(tong)信手段(duan)進行(xing)了系統的(de)改進和擴充,形(xing)成了“system V IPC”,通(tong)(tong)信進程(cheng)(cheng)(cheng)(cheng)局限在(zai)單個(ge)計算機內;后者(zhe)則(ze)跳過了該限制(zhi),形(xing)成了基(ji)(ji)于套接口(socket)的(de)進程(cheng)(cheng)(cheng)(cheng)間(jian)通(tong)(tong)信機制(zhi)。Linux則(ze)把兩者(zhe)繼承了下來,如圖示:

其中(zhong),初Unix IPC包(bao)括:管(guan)道(dao)、FIFO、信(xin)(xin)號(hao);System V IPC包(bao)括:System V消(xiao)息隊列、System V信(xin)(xin)號(hao)燈、System V共(gong)享內(nei)存(cun)區;Posix IPC包(bao)括: Posix消(xiao)息隊列、Posix信(xin)(xin)號(hao)燈、Posix共(gong)享內(nei)存(cun)區。有(you)兩(liang)點(dian)需(xu)要簡單說明一下:

1)由于Unix版本的(de)(de)多(duo)樣性,電子電氣工程協會(IEEE)開(kai)發了一(yi)個(ge)獨立(li)的(de)(de)Unix標準(zhun),這個(ge)新的(de)(de)ANSI Unix標準(zhun)被稱為計算機環境的(de)(de)可移植性操作系統界面(PSOIX)。現有大部分Unix和(he)流行版本都是遵循POSIX標準(zhun)的(de)(de),而Linux從一(yi)開(kai)始(shi)就遵循POSIX標準(zhun);

2)BSD并不(bu)是沒有涉足單機(ji)內(nei)的(de)進程(cheng)間通(tong)(tong)信(xin)(socket本身(shen)就(jiu)可以用于單機(ji)內(nei)的(de)進程(cheng)間通(tong)(tong)信(xin))。事實(shi)上,很多Unix版本的(de)單機(ji)IPC留(liu)有BSD的(de)痕跡,如4.4BSD支持(chi)的(de)匿名(ming)內(nei)存映射、4.3+BSD對可靠信(xin)號語義的(de)實(shi)現(xian)等(deng)等(deng)。

linux下進程間通(tong)信的幾種主要手(shou)段簡(jian)介:

1.管道

管道是進程間通信中古老的方式,它包括無名管道和有名管道兩種,前者可用于具有親緣關系進程間的通信,即可用于父進程和子進程間的通信,后者額克服了管道沒有名字的限制,因此,除具有前者所具有的功能外,它還允許無親緣關系進程間的通信,即可用于運行于同一臺機器上的任意兩個進程間的通信。 
無名管道(dao)由(you)pipe()函(han)數(shu)創建:

#include <unistd.h>
      &nbsp; int pipe(int filedis[2]);

參數filedis返回兩個(ge)文件描述符:filedes[0]為讀而打(da)開,filedes[1]為寫而打(da)開。filedes[1]的輸(shu)出是filedes[0]的輸(shu)入(ru)。

在Linux系(xi)統(tong)下,有(you)名(ming)管(guan)(guan)道(dao)可由兩(liang)種(zhong)(zhong)方式(shi)創建:命令(ling)行方式(shi)mknod系(xi)統(tong)調用和函數mkfifo。下面的兩(liang)種(zhong)(zhong)途徑都在當前目錄下生成了一個名(ming)為myfifo的有(you)名(ming)管(guan)(guan)道(dao):

方式一(yi):mkfifo("myfifo","rw&quot;);

方式二:mknod myfifo p

生成了有名管道(dao)后,就可以(yi)使用一般的(de)文件I/O函數(shu)如open、close、read、write等來(lai)對它進行操作(zuo)。

2.消息隊列

消(xiao)息(xi)(xi)(xi)隊(dui)列(lie)(lie)是(shi)消(xiao)息(xi)(xi)(xi)的(de)鏈接(jie)表(biao),包(bao)括Posix消(xiao)息(xi)(xi)(xi)隊(dui)列(lie)(lie)system V消(xiao)息(xi)(xi)(xi)隊(dui)列(lie)(lie)。消(xiao)息(xi)(xi)(xi)隊(dui)列(lie)(lie)用(yong)于運行于同(tong)一(yi)臺機器上的(de)進程間通信,它和(he)管(guan)道(dao)很相似,有足夠權限的(de)進程可(ke)以向隊(dui)列(lie)(lie)中添(tian)加消(xiao)息(xi)(xi)(xi),被賦予讀權限的(de)進程則可(ke)以讀走隊(dui)列(lie)(lie)中的(de)消(xiao)息(xi)(xi)(xi)。消(xiao)息(xi)(xi)(xi)隊(dui)列(lie)(lie)克服了信號承載信息(xi)(xi)(xi)量少,管(guan)道(dao)只能承載無格式字(zi)節(jie)流以及緩沖(chong)區大小受限等缺(que)點(dian)。 我們(men)可(ke)以用(yong)流管(guan)道(dao)或(huo)者套接(jie)口的(de)方式來取(qu)代它。

3.共享內存

共享內存是運行在同一臺機器上的進程間通信快的方式,因為數據不需要在不同的進程間復制。通常由一個進程創建一塊共享內存區,其余進程對這塊內存區進行讀寫。共享內存往往與其它通信機制,如信號量結合使用,來達到進程間的同步及互斥。 
首先要(yao)用的函數是shmget,它獲得一個共享存儲標識(shi)符。

#include <sys/types.h> 
        #include <sys/ipc.h> 
        #include <sys/shm.h> 
        int shmget(key_t key, int size, int flag);

 這(zhe)(zhe)個(ge)函(han)(han)數(shu)(shu)(shu)有點類似大家熟悉的(de)(de)(de)malloc函(han)(han)數(shu)(shu)(shu),系統按照請求分配(pei)size大小的(de)(de)(de)內存(cun)用作共享內存(cun)。Linux系統內核中(zhong)每個(ge)IPC結構(gou)都有的(de)(de)(de)一個(ge)非負整數(shu)(shu)(shu)的(de)(de)(de)標(biao)識(shi)符,這(zhe)(zhe)樣(yang)對一個(ge)消(xiao)息(xi)隊列發送消(xiao)息(xi)時只要引用標(biao)識(shi)符就可以了。這(zhe)(zhe)個(ge)標(biao)識(shi)符是內核由IPC結構(gou)的(de)(de)(de)關鍵(jian)字(zi)得(de)到(dao)的(de)(de)(de),這(zhe)(zhe)個(ge)關鍵(jian)字(zi),就是上面(mian)第(di)一個(ge)函(han)(han)數(shu)(shu)(shu)的(de)(de)(de)key。數(shu)(shu)(shu)據類型key_t是在頭文件sys/types.h中(zhong)定義(yi)的(de)(de)(de),它是一個(ge)長整形的(de)(de)(de)數(shu)(shu)(shu)據。在我們后(hou)面(mian)的(de)(de)(de)章節中(zhong),還會碰(peng)到(dao)這(zhe)(zhe)個(ge)關鍵(jian)字(zi)。

當共(gong)享內存創(chuang)建后,其余進程可以調用(yong)shmat()將其連接到自身(shen)的(de)地址空間中(zhong)。

void *shmat(int shmid, void *addr, int flag);

shmid為shmget函數(shu)(shu)返(fan)回的(de)共享存儲標識符,addr和flag參數(shu)(shu)決定了(le)以(yi)什么方式來確定連接的(de)地址(zhi),函數(shu)(shu)的(de)返(fan)回值即是該(gai)進程(cheng)(cheng)數(shu)(shu)據段所連接的(de)實(shi)際地址(zhi),進程(cheng)(cheng)可以(yi)對此進程(cheng)(cheng)進行(xing)讀寫操作。

使用(yong)共(gong)(gong)享(xiang)存儲來(lai)實(shi)(shi)現(xian)進(jin)程間(jian)通(tong)信(xin)的注意點是(shi)對(dui)數據(ju)(ju)存取(qu)的同步,必須(xu)確保(bao)當一個進(jin)程去讀(du)取(qu)數據(ju)(ju)時(shi),它(ta)所想要(yao)的數據(ju)(ju)已經寫好了。通(tong)常(chang),信(xin)號(hao)量被要(yao)來(lai)實(shi)(shi)現(xian)對(dui)共(gong)(gong)享(xiang)存儲數據(ju)(ju)存取(qu)的同步,另(ling)外(wai),可(ke)以通(tong)過(guo)使用(yong)shmctl函數設置共(gong)(gong)享(xiang)存儲內存的某些標(biao)志位如SHM_LOCK、SHM_UNLOCK等(deng)來(lai)實(shi)(shi)現(xian)。

4。信號量

信(xin)號量(liang)又稱(cheng)為(wei)信(xin)號燈,它(ta)是(shi)(shi)用(yong)(yong)來協調不同進(jin)程(cheng)間的(de)數(shu)據對象的(de),而主要(yao)的(de)應(ying)用(yong)(yong)是(shi)(shi)前(qian)一(yi)(yi)節(jie)的(de)共享(xiang)內存方式(shi)的(de)進(jin)程(cheng)間通(tong)信(xin)。本質上,信(xin)號量(liang)是(shi)(shi)一(yi)(yi)個(ge)計數(shu)器,它(ta)用(yong)(yong)來記(ji)錄對某個(ge)資源(如共享(xiang)內存)的(de)存取狀況。一(yi)(yi)般說來,為(wei)了獲得共享(xiang)資源,進(jin)程(cheng)需要(yao)執行下列操作:

(1) 測試(shi)控制該(gai)資源的信號量。

(2) 若此信號(hao)量的值(zhi)為正,則(ze)允許進行使用該資源。進程將(jiang)進號(hao)量減(jian)1。

(3) 若此信號(hao)量為(wei)0,則該資源目前(qian)不可用,進(jin)(jin)程進(jin)(jin)入(ru)睡眠狀(zhuang)態(tai),直至信號(hao)量值(zhi)大于0,進(jin)(jin)程被喚醒,轉入(ru)步驟(1)。

(4) 當進程(cheng)不再使用一個信(xin)號(hao)量控制的資源時,信(xin)號(hao)量值加1。如果此時有進程(cheng)正在睡眠等待(dai)此信(xin)號(hao)量,則喚醒此進程(cheng)。

維護信(xin)號(hao)(hao)量(liang)狀(zhuang)態的(de)是(shi)Linux內核操作系(xi)統而不是(shi)用(yong)(yong)戶(hu)進(jin)程(cheng)。我們(men)可以從頭文件/usr/src/linux/include /linux /sem.h中看到內核用(yong)(yong)來維護信(xin)號(hao)(hao)量(liang)狀(zhuang)態的(de)各個(ge)(ge)結構的(de)定義。信(xin)號(hao)(hao)量(liang)是(shi)一(yi)(yi)(yi)(yi)個(ge)(ge)數據(ju)集(ji)合,用(yong)(yong)戶(hu)可以單獨使用(yong)(yong)這一(yi)(yi)(yi)(yi)集(ji)合的(de)每(mei)個(ge)(ge)元素(su)。要調用(yong)(yong)的(de)第一(yi)(yi)(yi)(yi)個(ge)(ge)函(han)數是(shi)semget,用(yong)(yong)以獲得一(yi)(yi)(yi)(yi)個(ge)(ge)信(xin)號(hao)(hao)量(liang)ID。

#include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/sem.h>
        int semget(key_t key, int nsems, int flag);

key是(shi)前面講過的(de)(de)IPC結構的(de)(de)關鍵字(zi),它將來(lai)決定(ding)是(shi)創建新的(de)(de)信(xin)(xin)號量(liang)(liang)集合(he),還是(shi)引用(yong)一(yi)個現(xian)有的(de)(de)信(xin)(xin)號量(liang)(liang)集合(he)。nsems是(shi)該集合(he)中(zhong)的(de)(de)信(xin)(xin)號量(liang)(liang)數。如果(guo)(guo)是(shi)創建新集合(he)(一(yi)般在服務(wu)器中(zhong)),則必須(xu)指(zhi)定(ding)nsems;如果(guo)(guo)是(shi)引用(yong)一(yi)個現(xian)有的(de)(de)信(xin)(xin)號量(liang)(liang)集合(he)(一(yi)般在客戶機(ji)中(zhong))則將nsems指(zhi)定(ding)為0。

semctl函數(shu)用來對信號量進(jin)行操作(zuo)。

int semctl(int semid, int semnum, int cmd, union semun arg);

不(bu)同(tong)的(de)操作是通過(guo)cmd參(can)數來實(shi)現的(de),在頭(tou)文件sem.h中定義(yi)了7種不(bu)同(tong)的(de)操作,實(shi)際編程時可(ke)以參(can)照使用(yong)。

semop函數自動(dong)執行信號量集合上的操(cao)作數組。

int semop(int semid, struct sembuf semoparray[], size_t nops);

semoparray是一(yi)個(ge)指(zhi)針,它指(zhi)向一(yi)個(ge)信號量(liang)(liang)操作數組。nops規定該數組中(zhong)操作的數量(liang)(liang)。

下面,我們看一(yi)個(ge)具體的(de)例(li)子,它創(chuang)建(jian)(jian)一(yi)個(ge)特定的(de)IPC結構的(de)關鍵字和一(yi)個(ge)信(xin)(xin)號(hao)量,建(jian)(jian)立(li)此信(xin)(xin)號(hao)量的(de)索引,修改索引指向的(de)信(xin)(xin)號(hao)量的(de)值,后我們清除信(xin)(xin)號(hao)量。

5.套接口

套(tao)(tao)接口(kou)(kou)(socket)編程(cheng)(cheng)是(shi)實現(xian)Linux系統和其他(ta)大多數操(cao)作系統中進(jin)(jin)程(cheng)(cheng)間通信的(de)主要方式(shi)之一。我們(men)熟知的(de)WWW服務(wu)、FTP服務(wu)、TELNET服務(wu)等都是(shi)基于套(tao)(tao)接口(kou)(kou)編程(cheng)(cheng)來實現(xian)的(de)。除了在異地(di)的(de)計(ji)算機進(jin)(jin)程(cheng)(cheng)間以(yi)外,套(tao)(tao)接口(kou)(kou)同(tong)樣(yang)適用于本地(di)同(tong)一臺(tai)計(ji)算機內部的(de)進(jin)(jin)程(cheng)(cheng)間通信。

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)