对管道进行read时注意事项

  • Post author:
  • Post category:其他




read

#include<unistd.h>
ssize_t   read(int fd,void *buff,size_t bytes)

在unix下,read函数从打开文件中读取数据。今天在使用管道在父子进程之间进行信息交互时,对管道的read操作总不符合预期。我们都知道在对文件(如txt)进行读取时,文件末尾会自动补一个文件尾标志,即EOF,所以read返回值:返回读取的字节数,若已到文件尾,则返回0。但是对于管道来说,并不会给你添加额外的信息。所以对于管道进行read时,只有当管道非空时,read才会返回,或者父进程退出。



代码如下

  2 #include"iostream"
  3 #include<stdlib.h>
  4 #include<cstring>
  5 #include<unistd.h>
  6 #include<sys/wait.h>
  7 using namespace std;
  8 int main(int argc,char *argv[])
  9 {
 10     int fd[2];
 11     int n;
 12     pid_t pid;
 13     pipe(fd);
 14     char buff[64];

 19     pid=fork();
 20     if(pid== 0)
 21     {
 22         //child process
 23         close(fd[1]);
 24         cout<<"child process"<< endl;

 32             n=read(fd[0],buff,64); 
 33             int length=sizeof(buff); 
 34             buff[length-1]='\0'; 
 35             cout<<"the length of read"<< n<< endl; 
 36             cout<<buff<<endl; 

 39         cout<<"the cir is end ,n = "<< n<< endl;
 40         cout<<"child process exit"<< endl;
 41         exit(0);
 42     }
 43     else if(pid)
 44     {
 45         close(fd[0]);
 47         cout<<"parent process"<< endl;
 48         char str[64]="hello world nihao zhongxiao";
 50         int len=strlen(str);
 51         cout<<"len="<<len <<endl;
 54         sleep(10);
 55         write(fd[1],str,len);
 56         int status;
 57         waitpid(pid,&status,WNOHANG);
 58         if(WIFEXITED(status))
 59                 cout<<"child process has return"<< endl;
 63     }
			return 0;
		}



调试信息

根据代码,我们让父进程阻塞10秒,然后才向管道发送数据,然后在子进程的read下面一行打断点,如下图:

在33行打断点

然后调试子进程,(set follow-fork-mode child)

在这里插入图片描述

我们发现子进程并没有立刻执行到断点位置,而是10秒后才执行到断点,即read 10秒后才返回

10秒后输出:

在这里插入图片描述



结论

由此可见,read在对管道进行读取时,如果管道内无数据,则read会阻塞在那里。



版权声明:本文为qq_38297377原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。