當前位置:首頁 > 嵌入式 > 嵌入式教程
[導讀]通過編寫有名管道多路通信實驗,讀者可進一步掌握管道的創(chuàng)建、讀寫等操作,同時,也復習使用select()函數(shù)實現(xiàn)管道的通信。

8.7實驗內(nèi)容8.7.1管道通信實驗1.實驗目的

通過編寫有名管道多路通信實驗,讀者可進一步掌握管道的創(chuàng)建、讀寫等操作,同時,也復習使用select()函數(shù)實現(xiàn)管道的通信。

2.實驗內(nèi)容

讀者還記得在6.3.3小節(jié)中,通過mknod命令創(chuàng)建兩個管道的實例嗎?本實例只是在它的基礎上添加有名管道的創(chuàng)建,而不用再輸入mknod命令。

3.實驗步驟

(1)畫出流程圖。

該實驗流程圖如圖8.9所示。

圖8.98.6.1實驗流程圖

(2)編寫代碼。

該實驗源代碼如下所示。

/*pipe_select.c*/

#include<fcntl.h>

#include<stdio.h>

#include<unistd.h>

#include<stdlib.h>

#include<string.h>

#include<time.h>

#include<errno.h>

#defineFIFO1"in1"

#defineFIFO2"in2"

#defineMAX_BUFFER_SIZE1024/*緩沖區(qū)大小*/

#defineIN_FILES3/*多路復用輸入文件數(shù)目*/

#defineTIME_DELAY60/*超時值秒數(shù)*/

#defineMAX(a,b)((a>b)?(a):(b))

intmain(void)

{

intfds[IN_FILES];

charbuf[MAX_BUFFER_SIZE];

inti,res,real_read,maxfd;

structtimevaltv;

fd_setinset,tmp_inset;

fds[0]=0;

/*創(chuàng)建兩個有名管道*/

if(access(FIFO1,F_OK)==-1)

{

if((mkfifo(FIFO1,0666)<0)&&(errno!=EEXIST))

{

printf("Cannotcreatefifofilen");

exit(1);

}

}

if(access(FIFO2,F_OK)==-1)

{

if((mkfifo(FIFO2,0666)<0)&&(errno!=EEXIST))

{

printf("Cannotcreatefifofilen");

exit(1);

}

}

/*以只讀非阻塞方式打開兩個管道文件*/

if((fds[1]=open(FIFO1,O_RDONLY|O_NONBLOCK))<0)

{

printf("Openin1errorn");

return1;

}

if((fds[2]=open(FIFO2,O_RDONLY|O_NONBLOCK))<0)

{

printf("Openin2errorn");

return1;

}

/*取出兩個文件描述符中的較大者*/

maxfd=MAX(MAX(fds[0],fds[1]),fds[2]);

/*初始化讀集合inset,并在讀文件描述符集合中加入相應的描述集*/

FD_ZERO(&inset);

for(i=0;i<IN_FILES;i++)

{

FD_SET(fds[i],&inset);

}

FD_SET(0,&inset);

tv.tv_sec=TIME_DELAY;

tv.tv_usec=0;

/*循環(huán)測試該文件描述符是否準備就緒,并調(diào)用select()函數(shù)對相關文件描述符做相應操作*/

while(FD_ISSET(fds[0],&inset)

||FD_ISSET(fds[1],&inset)||FD_ISSET(fds[2],&inset))

{

/*文件描述符集合的備份,免得每次進行初始化*/

tmp_inset=inset;

res=select(maxfd+1,&tmp_inset,NULL,NULL,&tv);

switch(res)

{

case-1:

{

printf("Selecterrorn");

return1;

}

break;

case0:/*Timeout*/

{

printf("Timeoutn");

return1;

}

break;

default:

{

for(i=0;i<IN_FILES;i++)

{

if(FD_ISSET(fds[i],&tmp_inset))

{

memset(buf,0,MAX_BUFFER_SIZE);

real_read=read(fds[i],buf,MAX_BUFFER_SIZE);

if(real_read<0)

{

if(errno!=EAGAIN)

{

return1;

}

}

elseif(!real_read)

{

close(fds[i]);

FD_CLR(fds[i],&inset);

}

else

{

if(i==0)

{/*主程序終端控制*/

if((buf[0]=='q')||(buf[0]=='Q'))

{

return1;

}

}

else

{/*顯示管道輸入字符串*/

buf[real_read]='