亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        Linux管道通信淺析

        2013-12-31 00:00:00高霞曾輝鄧謙
        數(shù)字化用戶 2013年26期

        【摘 要】在Linux下,由于處于用戶態(tài)的不同進(jìn)程之間是彼此隔離的,它們必須通過某種機(jī)制來進(jìn)行通信。Linux平臺下提供了多種進(jìn)程通信方式,如管道、信號量、消息隊列等,本文主要研究了Linux環(huán)境中的管道通信的實(shí)現(xiàn)機(jī)制,探討無名管道和有名管道的工作方式,及相應(yīng)的創(chuàng)建和使用的方法。

        【關(guān)鍵詞】Linux、進(jìn)程通信、管道

        一、管道實(shí)現(xiàn)機(jī)制

        我們把從一個進(jìn)程連接到另一個進(jìn)程的數(shù)據(jù)流稱為 “管道”,這是最早的Linux進(jìn)程間通信機(jī)制之一。在Linux中管道常作為一種特殊文件處理。實(shí)際上,管道是內(nèi)核中一個固定大小的緩沖區(qū),它按先進(jìn)先出的方式進(jìn)行數(shù)據(jù)傳輸,一個進(jìn)程向管道中寫的內(nèi)容會被管道另一端的進(jìn)程讀出。每次寫入的內(nèi)容都添加在管道緩沖區(qū)的末尾,且從緩沖區(qū)的頭部讀出數(shù)據(jù),讀寫的位置自動增加,并且從管道讀數(shù)據(jù)是一次性操作,數(shù)據(jù)一旦被讀,便從管道中被拋棄。在緩沖區(qū)寫滿時,則由相應(yīng)的規(guī)則控制讀寫進(jìn)程進(jìn)入等待隊列,當(dāng)空的緩沖區(qū)有寫入數(shù)據(jù)或滿的緩沖區(qū)有數(shù)據(jù)讀出時,就喚醒等待隊列中的讀寫進(jìn)程繼續(xù)讀寫。

        管道分無名管道和有名管道。無名管道沒有文件名,也沒有磁盤節(jié)點(diǎn),僅作為一個內(nèi)存對象存在,用完后便銷毀。無名管道沒有顯式的打開過程,實(shí)際上它在創(chuàng)建時就自動打開了,故只能由有親緣關(guān)系的兩個進(jìn)程間通信使用。而有名管道克服了無名管道沒有名字的限制,可由任意兩個或多個進(jìn)程間通信使用,它的使用方法和普通文件類似,都遵循打開、讀、寫、關(guān)閉的過程,只是讀寫的內(nèi)部實(shí)現(xiàn)和普通文件有所不同。

        二、無名管道

        (一)無名管道創(chuàng)建

        int pipe(int fd[2])在Linux中可以通過系統(tǒng)調(diào)用建立管道。當(dāng)一個管道建立時,會創(chuàng)建兩個文件描述符fd [0]和fd [1],其中fd [0]固定用于讀管道,fd[1]固定用于寫管道,如圖1所示,這樣就構(gòu)成了一個半雙工通道。

        由于管道用于不同進(jìn)程間通信,而調(diào)用pipe()創(chuàng)建的管道兩端處于一個進(jìn)程中,這在實(shí)際應(yīng)用中沒有太大意義。因此,通常先是創(chuàng)建一個管道,再通過調(diào)用fork()函數(shù)創(chuàng)建子進(jìn)程,該子進(jìn)程會繼承父進(jìn)程所創(chuàng)建的管道,這時,父子進(jìn)程就可以共享該管道。管道的文件描述符對應(yīng)關(guān)系如圖2所示。此時關(guān)系看似非常復(fù)雜,實(shí)際上卻給不同進(jìn)程之間的讀寫創(chuàng)造了很好的條件。父子進(jìn)程分別擁有自己的讀寫通道,為了實(shí)現(xiàn)父子進(jìn)程之間的讀寫,只需把無關(guān)的讀端或?qū)懚宋募枋龇P(guān)閉即可。如在圖3中將父進(jìn)程的寫端fd[1]和子進(jìn)程的讀端fd[0]關(guān)閉,此時,父子進(jìn)程之間就建立起了一條“子進(jìn)程寫入父進(jìn)程讀取”的通道。反之,亦如此。

        (二) 無名管道讀寫操作

        創(chuàng)建完管道后,便可以調(diào)用I/O函數(shù),如close、read、write等函數(shù),對管道進(jìn)行讀寫了,但注意與普通文件讀寫還有一定區(qū)別。

        1.從無名管道中讀取數(shù)據(jù)。如果管道寫端不存在,則認(rèn)為已經(jīng)讀到了數(shù)據(jù)的末尾,讀函數(shù)返回的讀出字節(jié)數(shù)為0;

        當(dāng)管道寫端存在時,如果請求的字節(jié)數(shù)目大于PIPE_BUF,則返回管道中現(xiàn)有的數(shù)據(jù)字節(jié)數(shù),如果請求的字節(jié)數(shù)目不大于PIPE_BUF,則返回管道中現(xiàn)有數(shù)據(jù)字節(jié)數(shù)或返回請求的字節(jié)數(shù)。

        2.向無名管道中寫入數(shù)據(jù)。向管道中寫入數(shù)據(jù)時,Linux將不保證寫入的原子性,管道緩沖區(qū)一有空閑區(qū)域,寫進(jìn)程就會試圖向管道寫入數(shù)據(jù)。如果讀進(jìn)程不讀走管道緩沖區(qū)中的數(shù)據(jù),則寫操作將一直阻塞。

        三、有名管道

        有名管道建立在實(shí)際的磁盤介質(zhì)上,有自己的名字,它以FIFO的文件形式存在于文件系統(tǒng)中。故即使與FIFO的創(chuàng)建進(jìn)程不存在親緣關(guān)系的進(jìn)程,只要可以訪問該路徑,就能夠彼此通過FIFO相互通信。

        (一) 有名管道創(chuàng)建

        int mkfifo(const char * pathname, mode_t mode)

        該函數(shù)的第一個參數(shù)是路徑名,即創(chuàng)建后FIFO的名字。若該參數(shù)是一個已經(jīng)存在的路徑名時,會返回EEXIST錯誤,故在調(diào)用mkfifo函數(shù)前最好先檢查FIFO是否已經(jīng)創(chuàng)建。

        第二個參數(shù)與open()函數(shù)中的mode參數(shù)相同。如果程序在打開FIFO時指定了只讀/只寫方式,則該進(jìn)程對于打開的FIFO就是一個讀端/寫端。如果指定的是讀寫方式,進(jìn)程既是讀端又是寫端。

        (二) 有名管道的打開

        無名管道在創(chuàng)建時自動打開,但有名管道在使用時必須調(diào)用open()打開。因?yàn)闊o名管道有兩個文件數(shù)據(jù)結(jié)構(gòu):對應(yīng)的VFS索引節(jié)點(diǎn)及共享數(shù)據(jù)頁,在進(jìn)程每次運(yùn)行時都會創(chuàng)建一次,而FIFO一旦創(chuàng)建便一直存在。

        對管道使用open()時可能會引起阻塞。若同時用讀寫方式(O_RDWR)打開,則不會引起阻塞;若用只讀方式(O_RDONLY)打開,則open()會阻塞一直到有寫方打開管道, 除非指定了非阻塞方式(O_NONBLOCK)打開;若以只寫方式(O_WRONLY)打開也會阻塞到有讀方打開管道。

        (三) 有名管道的讀寫

        對有名管道的讀寫可以直接調(diào)用read()、write()函數(shù)實(shí)現(xiàn),但在管道的讀寫中可能有阻塞情況,我們可以在open()函數(shù)中設(shè)定非阻塞標(biāo)志(O_NONBLOCK)。

        1.從FIFO中讀取數(shù)據(jù)。如果有進(jìn)程寫打開FIFO,且當(dāng)前FIFO內(nèi)沒有數(shù)據(jù),則對設(shè)置了阻塞標(biāo)志的讀操作將一直阻塞。對沒有設(shè)置阻塞標(biāo)志讀操作來說則返回-1。對設(shè)置了阻塞標(biāo)志的讀操作來說,造成阻塞的原因有兩種:當(dāng)前FIFO內(nèi)有數(shù)據(jù),但有其它進(jìn)程在讀這些數(shù)據(jù)或是FIFO內(nèi)沒有數(shù)據(jù)。解阻塞的原因則是FIFO中有新的數(shù)據(jù)寫入。

        2.向FIFO中寫入數(shù)據(jù)。對于設(shè)置了阻塞標(biāo)志的寫操作,當(dāng)要寫入的數(shù)據(jù)量不大于PIPE_BUF時,Linux將保證寫入的原子性,若此時管道空閑緩沖區(qū)不足以容納要寫入的字節(jié)數(shù),則進(jìn)入睡眠,直到緩沖區(qū)中能夠容納要寫入的字節(jié)數(shù)時,才開始進(jìn)行一次性寫操作;當(dāng)要寫入的數(shù)據(jù)量大于PIPE_BUF時,Linux將不保證寫入的原子性,F(xiàn)IFO緩沖區(qū)一有空閑區(qū)域,寫進(jìn)程就會試圖向管道寫入數(shù)據(jù)。

        對于沒有設(shè)置阻塞標(biāo)志的寫操作,當(dāng)要寫入的數(shù)據(jù)量大于PIPE_BUF時,Linux不保證寫入的原子性,在寫滿所有FIFO空閑緩沖區(qū)后,寫操作返回;當(dāng)要寫入的數(shù)據(jù)量不大于PIPE_BUF時,Linux將保證寫入的原子性,若當(dāng)前FIFO空閑緩沖區(qū)能夠容納請求寫入的字節(jié)數(shù),寫完后成功返回;如果當(dāng)前FIFO空閑緩沖區(qū)不能夠容納請求寫入的字節(jié)數(shù),則返回EAGAIN錯誤,提醒以后再寫。

        四、 結(jié)束語

        管道是Linux平臺下最有特色的IPC方式之一,本文介紹了Linux中管道的實(shí)現(xiàn)機(jī)制,并詳細(xì)討論了無名管道和有名管道的創(chuàng)建及使用方法,指出無名管道用于親緣關(guān)系的進(jìn)程,而有名管道則可用于任何進(jìn)程之間。

        參考文獻(xiàn):

        [1]喬靜等,Linux兩種管道通信方式分析及對比,電腦知識與技術(shù),V01.6,No.24,August 2010

        [2]周超,董軍軍,Linux進(jìn)程管道通信的研究,電腦開發(fā)與應(yīng)用,2008(1)

        [3]楊水清等,ARM嵌入式Linux系統(tǒng)開發(fā)技術(shù)詳解,北京:電子工業(yè)出版社,2008

        [4]DanielP. Bovet等, 深入理解Linux內(nèi)核, 中國電力出版社, 2008

        作者簡介:高霞,女,1980年11月,湖北十堰,武昌理工學(xué)院信息工程學(xué)院講師,嵌入式方向

        日韩精品人妻少妇一区二区| 中文字幕日韩精品无码内射| 狠狠爱无码一区二区三区| 欧美日韩一区二区三区视频在线观看 | 人妻在线中文字幕| 极品少妇被后入内射视| 亚洲国产cao| 久久天堂av综合合色| 国产亚洲精品熟女国产成人| 日本japanese丰满多毛| 色丁香色婷婷| 亚洲国产精品一区亚洲国产| 国产在线观看自拍av| 亚洲日韩国产一区二区三区在线| 一区二区日韩国产精品| 91青青草在线观看视频| 白白在线视频免费观看嘛| 4399理论片午午伦夜理片| 9999毛片免费看| 日本视频一区二区三区免费观看| 成人自拍视频国产一区| 国产不卡在线观看视频| 麻豆tv入口在线看| 久久久精品久久波多野结衣av | 免费看泡妞视频app| 人妻av一区二区三区av免费| 凹凸世界视频a一二三| 免费无码一区二区三区a片百度 | 亚洲女同精品一区二区久久| 中文字幕一区,二区,三区| 久久av粉嫩一区二区| 人妻 色综合网站| 亚洲a∨天堂男人无码| 人妻少妇中文字幕av| 国产精品国产三级国产av剧情 | 久久伊人网久久伊人网| 日本久久精品中文字幕| 人人妻人人妻人人片av| 91精品国产免费青青碰在线观看 | 色一情一乱一伦一视频免费看| 国产午夜影视大全免费观看|