对管道进行read时注意事项
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下面一行打断点,如下图:
然后调试子进程,(set follow-fork-mode child)
我们发现子进程并没有立刻执行到断点位置,而是10秒后才执行到断点,即read 10秒后才返回
10秒后输出:
结论
由此可见,read在对管道进行读取时,如果管道内无数据,则read会阻塞在那里。