新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > linux操作系統(tǒng)下的進程通信的設(shè)計

        linux操作系統(tǒng)下的進程通信的設(shè)計

        作者: 時間:2010-01-27 來源:網(wǎng)絡(luò) 收藏

        linux下的手段基本上是從Unix平臺上的手段繼承而來的。而對Unix發(fā)展做出重大貢獻的兩大主力ATamp;T的貝爾實驗室及BSD(加州大學(xué)伯克利分校的伯克利軟件發(fā)布中心)在方面的側(cè)重點有所不同。前者對Unix早期的進程間通信手段進行了系統(tǒng)的改進和擴充,形成了“system V IPC”,通信進程局限在單個計算機內(nèi);后者則跳過了該限制,形成了基于套接口(socket)的進程間通信機制。則把兩者繼承了下來,如圖示:

        其中,最初Unix IPC包括:、FIFO、信號;System V IPC包括:System V消息隊列、System V信號燈、System V共享內(nèi)存區(qū);Posix IPC包括:Posix消息隊列、Posix信號燈、Posix共享內(nèi)存區(qū)。有兩點需要簡單說明一下:

        1)由于Unix版本的多樣性,電子電氣工程協(xié)會(IEEE)開發(fā)了一個獨立的Unix標準,這個新的ANSI Unix標準被稱為計算肪車目梢浦殘圓僮饗低辰緱媯≒SOIX)。現(xiàn)有大部分Unix和流行版本都是遵循POSIX標準的,而從一開始就遵循POSIX標準;

        2)BSD并不是沒有涉足單機內(nèi)的進程間通信(socket本身就可以用于單機內(nèi)的進程間通信)。事實上,很多Unix版本的單機IPC留有BSD的痕跡,如4.4BSD支持的匿名內(nèi)存映射、4.3+BSD對可靠信號語義的實現(xiàn)等等。

        linux下進程間通信的幾種主要手段簡介:

        1.

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

        無名管道由pipe()函數(shù)創(chuàng)建:

        #include unistd.h>

        int pipe(int filedis[2]);

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

        系統(tǒng)下,有名管道可由兩種方式創(chuàng)建:命令行方式mknod系統(tǒng)調(diào)用和函數(shù)mkfifo。下面的兩種途徑都在當(dāng)前目錄下生成了一個名為myfifo的有名管道:

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

        方式二:mknod myfifo p

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

        2.消息隊列

        消息隊列是消息的鏈接表,包括Posix消息隊列system V消息隊列。消息隊列用于運行于同一臺機器上的進程間通信,它和管道很相似,有足夠權(quán)限的進程可以向隊列中添加消息,被賦予讀權(quán)限的進程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點。

        我們可以用流管道或者套接口的方式來取代它。

        3.共享內(nèi)存

        共享內(nèi)存是運行在同一臺機器上的進程間通信最快的方式,因為數(shù)據(jù)不需要在不同的進程間復(fù)制。通常由一個進程創(chuàng)建一塊共享內(nèi)存區(qū),其余進程對這塊內(nèi)存區(qū)進行讀寫。共享內(nèi)存往往與其它通信機制,如信號量結(jié)合使用,來達到進程間的同步及互斥。

        首先要用的函數(shù)是shmget,它獲得一個共享存儲標識符。

        #include sys/types.h>

        #include sys/ipc.h>

        #include sys/shm.h>

        int shmget(key_t key, int size, int flag);

        這個函數(shù)有點類似大家熟悉的malloc函數(shù),系統(tǒng)按照請求分配size大小的內(nèi)存用作共享內(nèi)存。Linux系統(tǒng)內(nèi)核中每個IPC結(jié)構(gòu)都有的一個非負整數(shù)的標識符,這樣對一個消息隊列發(fā)送消息時只要引用標識符就可以了。這個標識符是內(nèi)核由IPC結(jié)構(gòu)的關(guān)鍵字得到的,這個關(guān)鍵字,就是上面第一個函數(shù)的key。數(shù)據(jù)類型key_t是在頭文件sys/types.h中定義的,它是一個長整形的數(shù)據(jù)。在我們后面的章節(jié)中,還會碰到這個關(guān)鍵字。

        當(dāng)共享內(nèi)存創(chuàng)建后,其余進程可以調(diào)用shmat()將其連接到自身的地址空間中。

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

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

        使用共享存儲來實現(xiàn)進程間通信的注意點是對數(shù)據(jù)存取的同步,必須確保當(dāng)一個進程去讀取數(shù)據(jù)時,它所想要的數(shù)據(jù)已經(jīng)寫好了。通常,信號量被要來實現(xiàn)對共享存儲數(shù)據(jù)存取的同步,另外,可以通過使用shmctl函數(shù)設(shè)置共享存儲內(nèi)存的某些標志位如SHM_LOCK、SHM_UNLOCK等來實現(xiàn)。

        4. 信號量

        信號量又稱為信號燈,它是用來協(xié)調(diào)不同進程間的數(shù)據(jù)對象的,而最主要的應(yīng)用是前一節(jié)的共享內(nèi)存方式的進程間通信。本質(zhì)上,信號量是一個計數(shù)器,它用來記錄對某個資源(如共享內(nèi)存)的存取狀況。一般說來,為了獲得共享資源,進程需要執(zhí)行下列操作:

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

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

        (3) 若此信號量為0,則該資源目前不可用,進程進入睡眠狀態(tài),直至信號量值大于0,進程被喚醒,轉(zhuǎn)入步驟(1)。

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

        維護信號量狀態(tài)的是Linux內(nèi)核操作系統(tǒng)而不是用戶進程。我們可以從頭文件/usr/src/linux/include/linux/sem.h中看到內(nèi)核用來維護信號量狀態(tài)的各個結(jié)構(gòu)的定義。信號量是一個數(shù)據(jù)集合,用戶可以單獨使用這一集合的每個元素。要調(diào)用的第一個函數(shù)是semget,用以獲得一個信號量ID。

        #include sys/types.h>

        #include sys/ipc.h>

        #include sys/sem.h>

        int semget(key_t key, int nsems, int flag);

        key是前面講過的IPC結(jié)構(gòu)的關(guān)鍵字,它將來決定是創(chuàng)建新的信號量集合,還是引用一個現(xiàn)有的信號量集合。nsems是該集合中的信號量數(shù)。如果是創(chuàng)建新集合(一般在服務(wù)器中),則必須指定nsems;如果是引用一個現(xiàn)有的信號量集合(一般在客戶機中)則將nsems指定為0。

        semctl函數(shù)用來對信號量進行操作。

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

        不同的操作是通過cmd參數(shù)來實現(xiàn)的,在頭文件sem.h中定義了7種不同的操作,實際編程時可以參照使用。

        semop函數(shù)自動執(zhí)行信號量集合上的操作數(shù)組。

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

        semoparray是一個指針,它指向一個信號量操作數(shù)組。nops規(guī)定該數(shù)組中操作的數(shù)量。

        下面,我們看一個具體的例子,它創(chuàng)建一個特定的IPC結(jié)構(gòu)的關(guān)鍵字和一個信號量,建立此信號量的索引,修改索引指向的信號量的值,最后我們清除信號量。

        5.套接口

        套接口(socket)編程是實現(xiàn)Linux系統(tǒng)和其他大多數(shù)操作系統(tǒng)中進程間通信的主要方式之一。我們熟知的WWW服務(wù)、FTP服務(wù)、TELNET服務(wù)等都是基于套接口編程來實現(xiàn)的。除了在異地的計算機進程間以外,套接口同樣適用于本地同一臺計算機內(nèi)部的進程間通信。

        linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


        關(guān)鍵詞: Linux 進程 通信 管道

        評論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 西宁市| 二手房| 龙里县| 淮南市| 临潭县| 襄樊市| 中超| 青龙| 贵港市| 敦化市| 同德县| 朝阳县| 确山县| 遂溪县| 富蕴县| 且末县| 卓资县| 繁峙县| 磐石市| 北安市| 和林格尔县| 横山县| 同德县| 若尔盖县| 渭源县| 米易县| 南木林县| 涪陵区| 天台县| 洛川县| 玉山县| 巴彦县| 璧山县| 武乡县| 宜章县| 河曲县| 胶州市| 平江县| 若羌县| 斗六市| 阿拉善左旗|