博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
匿名管道
阅读量:5305 次
发布时间:2019-06-14

本文共 3840 字,大约阅读时间需要 12 分钟。

由于匿名管道使用的是文件描述符,所以我们只能用read和write对其进行读写。因为标准读写函数都是基于文件指针的。

当read成功时,返回值为读到的字符数。当遇见文件结尾时,返回0(也就是什么都读不出来了)。出错,返回-1。—> 参考 man 2 read

当write成功时,返回值为写入的字符数。返回0代表什么也没有写入。出错返回-1。 –> 参考 man 2 write

 

#include
#include
#include
#include
int main(int argc, char* argv[]){ int fds[2];//fds[0]-r fds[1] - w //writ(fds[1]) read(fds[0]) if(pipe(fds) == -1) { perror("pipe"); exit(1); } if(fork() == 0)//child read { printf("child : %u \n", getpid()); close(fds[1]); /* 关闭子进程的写 */ char buf[1024]= ""; while(1) { memset(buf, 0, 1024); if(read(fds[0], buf, 1024) == 0) { break ; } printf("child : read : %s\n", buf); } printf("child exit ! \n"); exit(1); }else // parent write { printf("parent : %u \n", getpid()); close(fds[0]); /* 关闭父进程的读 */ char buf[1024]; while(memset(buf,0, 1024), fgets(buf, 1024, stdin) != NULL) { write(fds[1], buf, strlen(buf)); } close(fds[1]); /* c+d后退出循环,当父进程不准备读了,要关闭父进程的写 */ printf("parent bread while! \n"); wait(NULL); } return 0 ;}
parent : 2829child : 2830how are youchild : read : how are youbaby U R beautifulchild : read : baby U R beautifulparent bread while!child exit !

观察程序运行结果,首先输出的是parent:2829,显然先执行的是父进程,之后一直执行到父进程的while循环,由于循环中有fgets,其为阻塞函数,此时内核把时间片给子进程。

子进程打印出child:2830后一直往下执行,直到while循环,在read处阻塞,等待输入,此时时间片到达父进程,父进程write后(注意由于fgets会接受换行符,因此每次write都会刷新缓冲区),子进程就读。

直到父进程按c+d退出while循环,关闭父进程的写,wait挂起后,将时间片给子进程。由于写端关闭,子进程read函数必定读不到东西,退出循环,执行exit,退出,同时exit唤醒父进程,父进程退出。

注意:如果父进程退出循环后,但不关闭其写端,子进程会一直等待输入,不会认为自己读不到东西。

 

 

在关闭子进程的写端语句后,再加上一条关闭子进程的读端语句,如下:

if(fork() == 0)//child read    {        printf("child : %u \n", getpid());        close(fds[1]);          /* 关闭子进程的写 */        close(fds[0]);          /* 关闭子进程的读 */  /* 新加的语句 */        char buf[1024]= "";        while(1)        {            memset(buf, 0, 1024);            if(read(fds[0], buf, 1024) == 0)            {                break ;            }            printf("child : read : %s\n", buf);        }        printf("child exit ! \n");        exit(1);    } 此时,执行到子进程的while循环后,会一直不断输出:
child : read :child : read :child : read :child : read :child : read :child : read :
程序进入死循环。原因是当子进程的读端已经关闭后,再读管道,必然出错,也就是此时read调用的返回值是-1。因此不断执行打印语句,陷入死循环。
if(read(fds[0], buf, 1024) == -1) 将程序中的此句改成-1可以避免上面的死循环 如下
#include
#include
#include
#include
int main(int argc, char* argv[]){ int fds[2];//fds[0]-r fds[1] - w //writ(fds[1]) read(fds[0]) if(pipe(fds) == -1) { perror("pipe"); exit(1); } if(fork() == 0)//child read { printf("child : %u \n", getpid()); close(fds[1]); /* 关闭子进程的写 */ close(fds[0]); /* 关闭子进程的读 */ char buf[1024]= ""; while(1) { memset(buf, 0, 1024); if(read(fds[0], buf, 1024) == -1) { break ; } printf("child : read : %s\n", buf); } printf("child exit ! \n"); exit(1); }else // parent write { printf("parent : %u \n", getpid()); close(fds[0]); /* 关闭父进程的读 */ char buf[1024]; while(memset(buf,0, 1024), fgets(buf, 1024, stdin) != NULL) { write(fds[1], buf, strlen(buf)); } close(fds[1]); /* c+d后退出循环,当父进程不准备读了,要关闭父进程的写 */ printf("parent bread while! \n"); wait(NULL); } return 0 ;} 当程序执行到父进程的while循环时,我们输入“how are you”,由于此时子进程的读端已经关闭,我们再往写端写东西,内核直接发信号,挂掉我们的程序。即输入“how are you”后,程序直接退出。

转载于:https://www.cnblogs.com/hxjbc/p/3958449.html

你可能感兴趣的文章
python升级安装后的yum的修复
查看>>
Vim配置Node.js开发工具
查看>>
iOS开发者需要的5款排版工具
查看>>
web前端面试题2017
查看>>
Reflection in Teaching
查看>>
intellij idea 将模块打jar包
查看>>
给MySQL增加Sequence管理功能
查看>>
ELMAH——可插拔错误日志工具
查看>>
MySQL学习笔记(四)
查看>>
【Crash Course Psychology】2. Research & Experimentation笔记
查看>>
两数和
查看>>
Python subprocess 模块
查看>>
Http协议
查看>>
c#获取文件路径
查看>>
移动设备和SharePoint 2013 - 第3部分:推送通知
查看>>
SOPC Builder中SystemID
查看>>
MySQL数据库备份工具mysqldump的使用(转)
查看>>
SSL 1120——【USACO 2.4】回家[最短路]
查看>>
Python学习之路:新式类VS经典类
查看>>
Oracle数据库和实例
查看>>