0、章节引用
1、课堂目标
2、读取无名管道
- 写端存在(至少有一个进程存在写端的文件描述符)的情况
- 1、管道内有数据时,read读取会返回实际读取的字节数。
- 2、管道内无数据时,read会读堵塞。
- 写端不存在(所有进程都关闭写端文件描述符)
- 1、管道内有数据时,read读取会返回实际读取的字节数。
- 2、管道内无数据时,read会返回0。
- 注意:一般情况写入数据后会关闭写端,读端可以根据read返回的数据判断写端是否结束。
3、读端存在
- 读端存在(至少有一个进程存在读端的文件描述符)的情况
- 1、管道中有足够的空间时,write会返回实际写入的字节数
- 2、管道中空间不足时,写入数据会先占满管道,之后的数据由于没有空间会等待写入,导致write堵塞,直到有空间将数据全部写入管道。
- 读端不存在(所有进程都关闭读端的文件描述符)的情况
- 1、不管是有空间。都会导致管道断裂,无法写入成功,会被信号13退出进程。
4、无名管道- 思考
- 如何获取无名管道的大小?
- 循环写入管道,直到堵塞,统计循环的次数。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
int main(void)
{
int count = 0;
int pfd[2];
char buf[1024];
memset(buf,0x0,sizeof(buf));
if(pipe(pfd)<0)
{
perror("pipe");
exit(-1);
}
while(1)
{
if(write(pfd[1],buf,1024)!= -1)
{
count++;
printf("times = %d\n",count);
}
}
return 0;
}
times = 1
times = 2
...(省略中间信息)
times = 63
times = 64
(等待写入成功)
5、无名管道- 思考2
- 如何验证管道断裂(进程被信号结束)?
- 通过父进程关闭读端,之后子进程写入管道,父进程回收子进程的结束状态,查看是否为信号结束。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>
int main(void)
{
int pfd[2];
int status;
char buf[32];
pid_t pid;
strcpy(buf,"123123123");
if(pipe(pfd)<0)
{
perror("pipe");
exit(-1);
}
close(pfd[0]);
if((pid = fork())<0)
{
perror("fork");
exit(-1);
}
else if(pid == 0)
{
sleep(1);
write(pfd[1],buf,32);
printf("123123123\n");
}
else
{
wait(&status);
printf("status = %x\n",status);
}
return 0;
}
6、无名管道小结
- 无名管道读特性(写端存在,无数据时读数据堵塞,)
- 无名管道写特性(读端存在,没有空间,写端会堵塞。没有读端时会断裂,进程结束)
欢迎关注微信工作号,推送文章更及时。
