linux管道的那點事

原文地址:http://blog.chinaunix.net/uid-27034868-id-3394243.html

管道是一種兩個進程間進行單向通信的機制毅臊。因為管道傳遞數(shù)據(jù)的單向性熬苍,管道又稱為半雙工管道柴底。管道的這一特點決定了器使用的局限性梦裂。管道是Linux支持的最初Unix IPC形式之一年柠,具有以下特點:

***數(shù)據(jù)只能由一個進程流向另一個進程(其中一個讀管道冗恨,一個寫管道)味赃;如果要進行雙工通信心俗,需要建 立兩個管道城榛。

***管道只能用于父子進程或者兄弟進程間通信狠持。,也就是說管道只能用于具有親緣關系的進程間通信甜刻。

除了以上局限性得院,管道還有其他一些不足尿招,如管道沒有名字(匿名管道)就谜,管道的緩沖區(qū)大小是受限制的丧荐。管道所傳輸?shù)氖菬o格式的字節(jié)流虹统。這就需要管道輸入方和輸出方事先約定好數(shù)據(jù)格式车荔。雖然有那么多不足忧便,但對于一些簡單的進程間通信珠增,管道還是完全可以勝任的。

使用管道進行通信時巍举,兩端的進程向管道讀寫數(shù)據(jù)是通過創(chuàng)建管道時懊悯,系統(tǒng)設置的文件描述符進行的定枷。從本質上說欠窒,管道也是一種文件岖妄,但它又和一般的文件有所不同荐虐,可以克服使用文件進行通信的兩個問題福扬,這個文件只存在內存中铛碑。

通過管道通信的兩個進程汽烦,一個進程向管道寫數(shù)據(jù)撇吞,另外一個從中讀數(shù)據(jù)牍颈。寫入的數(shù)據(jù)每次都添加到管道緩沖區(qū)的末尾煮岁,讀數(shù)據(jù)的時候都是從緩沖區(qū)的頭部讀出數(shù)據(jù)的人乓。

#include

int pipe(int pipefd[2]);

(匿名)管道兩端分別用描述符pipefd[0]及pipefd[1]來描述色罚。需要注意的是戳护,管道兩端的任務是固定的腌且,一端只能用于讀铺董,有描述符pipefd[0]表示精续,稱其為管道讀端重付;另一端只能用于寫弓颈,由描述符pipe[1]來表示删掀,稱其為管道寫端橘蜜。該函數(shù)創(chuàng)建的管道的兩端處于一個進程中間计福,在實際應用中沒有太大意義象颖,因此,一個進程在由pipe()創(chuàng)建管道后陶冷,一般再fork一個子進程埂伦,然后通過管道實現(xiàn)父子進程間的通信。在此不再作多介紹基跑,下面看看有名管道吧媳否。

管道的一個不足之處就是沒有名字,因此室抽,只能用于具有親緣關系的進程間通信晓折,在有名管道(name pipe或FIFO)提出后漓概,該限制得到了解決。FIFO不同與管道之處在與她提供一個路徑名與之關聯(lián)觅彰,以FIFO的文件形式存儲在文件系統(tǒng)中。有名管道是一個設備文件飒责,因此,即使進程與創(chuàng)建FIFO的進程不存在親緣關系拾并,只要可以訪問該路徑个榕,就能夠通過FIFO相互通信了凰萨。值得注意的是FIFO(First In First Out)總是按照先進先出的原則工作胖眷,第一個被寫入的數(shù)據(jù)首先從管道中讀出。

在Linux中我們經常使用管道重定向數(shù)據(jù)囚枪。比如:

下面介紹一下創(chuàng)建有名管道的系統(tǒng)調用沛鸵,有兩個疾捍,mknod和mkfifo

#include?

#include?

int mknod(const char *pathname, mode_t mode, dev_t dev);

int?mkfifo(?const?char?*pathname,?mode_t?mode?);

函數(shù)mknod參數(shù)中pathname為創(chuàng)建有名管道的全路徑名,mode為創(chuàng)建有名管道的模式,指明其存取權限疲酌;dev為設備值,該值取決于文件創(chuàng)建的種類,它只在創(chuàng)建設備文件是才會用到。這兩個函數(shù)調用成功都返回0执赡,否則返回-1.

讀寫有名管道:

#include?

ssize_t?read?(int?fd?,?void?*?buf?,?size_t?nbytes)

ssize_t?write?(int?fd?,?void?*?buf?,?size_t?nbytes)

接下來給大家演示一下通過有名管道通信的聊天程序跌帐。即舌。盯仪。

點擊(此處)折疊或打開

//李四.c

#include

#include

#include

#include

#include

#include

#include

#include

#define FIFO_READ"writefifo"http://另外一個程序只要把本程序

#define FIFO_WRITE"readfifo"http://拷貝一份然后調換這兩個宏即可

#define BUF_SIZE????1024

intleft=0;

void*read_buf()

{

intrfd=-1;

char buf[BUF_SIZE]={'\0'};

inti;

printf("等待對方……\n");

while((rfd=open(FIFO_READ,O_RDONLY))==-1){

sleep(1);

}

while(left!=1){

//printf("i=%d ",i++);

intlen=read(rfd,buf,BUF_SIZE);

if(len>0){

buf[len]='\0';

if(strcmp(buf,"不理你了")==0){

printf("\n對方已經走開!\n");

left=1;

break;

//exit(0);

}

for(i=0;i

printf("\b");

printf("對方:%s\n",buf);

printf("我:");

fflush(stdout);

}

}

close(rfd);

returnNULL;

}

void*write_to()

{

intwfd;

char buf[BUF_SIZE];

intlen;

umask(0);

if(mkfifo(FIFO_WRITE,S_IFIFO|0666)){

printf("Can't create FIFO %s because %s",FIFO_WRITE,

strerror(errno));

exit(1);

}

umask(0);

wfd=open(FIFO_WRITE,O_WRONLY);

if(wfd==-1){

printf("open FIFO %s error: %s",FIFO_WRITE,strerror(errno));

exit(1);

}

while(left!=1){

printf("我: ");

fgets(buf,BUF_SIZE,stdin);

buf[strlen(buf)-1]='\0';

if(strcmp(buf,"不理你了")==0||left==1){

write(wfd,buf,strlen(buf));//通知對方

close(wfd);

unlink(FIFO_WRITE);

exit(0);

}

write(wfd,buf,strlen(buf));

fflush(stdin);

}

}

intmain(intargc,char*argv[])

{

pthread_t thIDr,thIDw;

pthread_create(&thIDr,NULL,(void*)read_buf,NULL);

pthread_create(&thIDw,NULL,(void*)write_to,NULL);

pthread_join(thIDr,NULL);

pthread_join(thIDw,NULL);

return 0;

}

學以置用全景,呵呵耀石,效果如下:

注:本博客的文章除注明有“轉載”字樣的外,均為原創(chuàng)爸黄,歡迎轉載滞伟,請注明文字出處,謝謝炕贵!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末梆奈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子称开,更是在濱河造成了極大的恐慌亩钟,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鳖轰,死亡現(xiàn)場離奇詭異清酥,居然都是意外死亡,警方通過查閱死者的電腦和手機蕴侣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門焰轻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人睛蛛,你說我怎么就攤上這事鹦马‰侍福” “怎么了忆肾?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長菱肖。 經常有香客問我客冈,道長,這世上最難降的妖魔是什么稳强? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任场仲,我火速辦了婚禮和悦,結果婚禮上,老公的妹妹穿的比我還像新娘渠缕。我一直安慰自己鸽素,他們只是感情好,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布亦鳞。 她就那樣靜靜地躺著馍忽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪燕差。 梳的紋絲不亂的頭發(fā)上遭笋,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天,我揣著相機與錄音徒探,去河邊找鬼瓦呼。 笑死,一個胖子當著我的面吹牛测暗,可吹牛的內容都是我干的央串。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼碗啄,長吁一口氣:“原來是場噩夢啊……” “哼蹋辅!你這毒婦竟也來了?” 一聲冷哼從身側響起挫掏,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤侦另,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后尉共,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體褒傅,經...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年袄友,在試婚紗的時候發(fā)現(xiàn)自己被綠了殿托。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡剧蚣,死狀恐怖支竹,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情鸠按,我是刑警寧澤礼搁,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站目尖,受9級特大地震影響馒吴,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一饮戳、第九天 我趴在偏房一處隱蔽的房頂上張望豪治。 院中可真熱鬧,春花似錦扯罐、人聲如沸负拟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽齿椅。三九已至,卻和暖如春启泣,著一層夾襖步出監(jiān)牢的瞬間涣脚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工寥茫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遣蚀,地道東北人。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓纱耻,卻偏偏與公主長得像芭梯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子弄喘,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內容