标签:匿名管道
通信:因为进程有强大独立性,当想把自己数据交给另一个进程,需要通信。
通信本质:让不同进程看到相同资源。
匿名管道:管道:通过某种机制传递资源(数据),匿名管道只适用于有血缘关系的进程,一般用于父,子进程通信。
a.创建管道
b.创建子进程
c.父,子进程关闭自己不需要的文件描述符
注意:匿名管道提供单向通信,父读子写或父写子读,若要实现双向通信,可再创建一个管道。
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{
int _pipefd[2]={-1,-1};
int ret=pipe(_pipefd);
if(ret==-1)
{
perror("pipe");
return 2;
}
pid_t id=fork();
if(id<0)
{
perror("fork");
return 2;
}
else if(id==0)
{
close(_pipefd[0]);
char buf[]="hello world";
int count=5;
while(count--)
{
write(_pipefd[1],buf,strlen(buf));
sleep(1);
}
}
else
{
close(_pipefd[1]);
char buf[1024]={0};
int count=5;
while(count--)
{
memset(buf,‘\0‘,sizeof(buf));
ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
buf[_size]=‘\0‘;
printf("buf:%s\n",buf);
}
}
return 0;
}使用管道需注意以下四种情况:
1.如果所有指向管道写端的文件描述符都关闭了,仍然有进程从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到文件末尾一样。
1 #include<stdio.h>
2 #include<string.h>
3 #include<unistd.h>
4 #include<sys/types.h>
5 #include<stdlib.h>
6 int main()
7 {
8 int _pipefd[2]={-1,-1};
9 int ret=pipe(_pipefd);
10 if(ret==-1)
11 {
12 perror("pipe");
13 return 2;
14 }
15
16 pid_t id=fork();
17 if(id<0)
18 {
19 perror("fork");
20 return 2;
21 }
22 else if(id==0)
23 {
24 close(_pipefd[0]);
25 char buf[]="hello world";
26 int count=5;
27 int i=0;
28 while(count--)
29 {
30 if(i==3)
31 {
32 printf("I want sleep\n");
33 break;
34 }
35 write(_pipefd[1],buf,strlen(buf));
36 sleep(1);
37 i++;
38 }
39 close(_pipefd[0]);
40 }
41 else
42 {
43 close(_pipefd[1]);
44 char buf[1024]={0};
45 int count=5;
46 while(count--)
47 {
48 memset(buf,‘\0‘,sizeof(buf));
49 ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
50 if(_size>0)
51 {
52 // buf[_size]=‘\0‘;
53 printf("buf:%s\n",buf);
54 }
55 }
56 }
57 //printf("%d ,%d \n",_pipefd[0],_pipefd[1]);
58 return 0;
59 }2.如果有指向管道写端的文件描述符没关闭,持有管道写端的进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。
//修改子进程代码为
else if(id==0)
23 {
24 close(_pipefd[0]);
25 char buf[]="hello world";
26 int count=5;
27 int i=0;
28 while(count--)
29 {
30 if(i==3)
31 {
32 sleep(10);
33 //printf("I want sleep\n");
34 // break;
35 }
36 write(_pipefd[1],buf,strlen(buf));
37 sleep(1);
38 i++;
39 }
40 // close(_pipefd[0]);
41 }3.如果所有指向管道读端的文件描述符都关闭了,这时有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止。
//修改父进程中代码为:
else
44 {
45 close(_pipefd[1]);
46 char buf[1024]={0};
47 int count=5;
48 while(count--)
49 {
50 if(count==3)
51 close(_pipefd[0]);
52 memset(buf,‘\0‘,sizeof(buf));
53 ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
54 if(_size>0)
55 {
56 // buf[_size]=‘\0‘;
57 printf("buf:%s\n",buf);
58 }
59 }
60 int status=0;
61 pid_t _pid=waitpid(id,&status,0);
62 printf("waitpid: %d,return status:%d\n",id,status&0xff);
63}4.如果有指向管道读端的文件描述符没关闭,持有管道读端的进程也没有从管道中读数据,这时有进程向管道写端写数据,那么在管道被写满时再次write会阻塞,直到管道中有空位置了才写入数据并返回。
//修改父进程中代码为:
else
44 {
45 close(_pipefd[1]);
46 char buf[1024]={0};
47 int count=5;
48 while(count--)
49 {}
50 int status=0;
51 pid_t _pid=waitpid(id,&status,0);
52 printf("waitpid: %d,return status:%d\n",id,status&0xff);
53}本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1762101
标签:匿名管道
原文地址:http://10541556.blog.51cto.com/10531556/1762101