加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 8.7  實(shí)驗(yàn)內(nèi)容
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

進(jìn)程間通信之:實(shí)驗(yàn)內(nèi)容

2013/09/13
閱讀需 28 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

?

8.7??實(shí)驗(yàn)內(nèi)容

8.7.1??管道通信實(shí)驗(yàn)

1.實(shí)驗(yàn)?zāi)康?/h4>

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

2.實(shí)驗(yàn)內(nèi)容

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

3.實(shí)驗(yàn)步驟

(1)畫出流程圖。

該實(shí)驗(yàn)流程圖如圖8.9所示。

圖8.9??8.6.1實(shí)驗(yàn)流程圖

(2)編寫代碼。

該實(shí)驗(yàn)源代碼如下所示。

/*?pipe_select.c*/

#include?<fcntl.h>

#include?<stdio.h>

#include?<unistd.h>

#include?<stdlib.h>

#include?<string.h>

#include?<time.h>

#include?<errno.h>

#define?FIFO1???????????????"in1"

#define?FIFO2???????????????"in2"

#define?MAX_BUFFER_SIZE?????????1024??????????/*?緩沖區(qū)大小*/

#define?IN_FILES????????????3???????????????????/*?多路復(fù)用輸入文件數(shù)目*/

#define?TIME_DELAY??????????60??????????????/*?超時(shí)值秒數(shù)?*/

#define?MAX(a,?b)???????????((a?>?b)?(a):(b))

int?main(void)

{

?????int?fds[IN_FILES];

?????char?buf[MAX_BUFFER_SIZE];

?????int?i,?res,?real_read,?maxfd;

?????struct?timeval?tv;

?????fd_set?inset,tmp_inset;

????

?????fds[0]?=?0;????????

????

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

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

?????{

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

????????{

????????????printf("Cannot?create?fifo?filen");

????????????exit(1);

????????}

?????}

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

?????{

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

????????{

????????????printf("Cannot?create?fifo?filen");

????????????exit(1);

????????}

?????}

????????

?????/*?以只讀非阻塞方式打開兩個(gè)管道文件?*/

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

?????{

????????printf("Open?in1?errorn");

????????return?1;

?????}

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

????{

????????printf("Open?in2?errorn");

????????return?1;

?????}

?????/*取出兩個(gè)文件描述符中的較大者*/

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

????/*初始化讀集合inset,并在讀文件描述符集合中加入相應(yīng)的描述集*/

????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)測(cè)試該文件描述符是否準(zhǔn)備就緒,并調(diào)用select()函數(shù)對(duì)相關(guān)文件描述符做相應(yīng)操作*/

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

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

????{?

?????/*?文件描述符集合的備份,?免得每次進(jìn)行初始化?*/

????????tmp_inset?=?inset;?

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

????????switch(res)

????????{

????????????case?-1:

????????????{

??????????????????printf("Select?errorn");

??????????????????return?1;

??????????????}

??????????????break;??????????????????

??????????????case?0:?/*?Timeout?*/

??????????????{

??????????????????printf("Time?outn");

??????????????????return?1;

???????????}

????????????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)

??????????????????????????????{

??????????????????????????????????return?1;

??????????????????????????????}

?????????????????????? ?????}

???????????????????????????else?if?(!real_read)

???????????????????????????{

???????????????????????????????close(fds[i]);

???????????????????????????????FD_CLR(fds[i],?&inset);

??????????????????????????}

??????????????????????????else

??????????????????????????{

???????????????????????????????if?(i?==?0)

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

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

???? ??????????????????????????????{

?????????? ???????? ??????????????????return?1;

???????????????????????????????}

???????????????????????????????}

???????????????????????????????else

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

???????????????????????????????????buf[real_read]?=?'