一、创建匿名管道:
#include
int pipe(int pipefd[2]);
作用:创建一个匿名管道,用来进程间通信;
参数:int pipefd[2]这个数组是一个传出参数;
pipefd[0] 对应管道的读端;
pipefd[1] 对应管道的写端;
返回值:
成功 0;
失败-1;
注意:匿名管道只能在具有公共祖先的进程(父与子进程、两个兄弟进程、亲戚之间)
二、查看管道缓冲大小的命令:ulimit -a
三、查看管道缓冲大小的函数:
#include
long fpathconf(int fd,int name);
代码如下:
#include
#include
#include
#include
#include
int main()
{
int pipefd[2];
int ret=pipe(pipefd);
long size=fpanthconf(pipefd[0],_PC_PIPE_BUF)//专门用来读取pipe的内存
printf("pipe size:%ld",size);
return 0;
}
运行结果如下:
4096个字节=4K
四、其特点为:
1、管道是一个在内核内存中维护的缓冲器;
2、管道拥有文件的特质:读和写操作。匿名管道没有文件实体,而有名管道有文件实体;
3、通过管道传递的数据是有顺序的,读的顺序和写的顺序是一致的;
4、管道中的数据传递方向是单向的,一端用于写入,另一端用于读取,半双工(单工:只能单向传输,如遥控器向电视发送信号,但电视不能给遥控器发送信号;双工:双向都能同时传输信号,如两个在打电话,一个说话的时候也不影响对方说话,双方都能同时收到对方的信息;半双工:一段时间内只能一个方向传输,如果这个方向传输完毕另一端也会反向传输过来,如对讲机);
5、从管道读数据是一次性的,数据一旦被读走,数据将会被抛弃,释放空间以便储存新的数据;
6、匿名管道只能在具有公共祖先的进程(父与子进程、两个兄弟进程、亲戚之间)使用。
五、管道的数据结构:环形队列。
六、代码实现:
1、首先制作一个简易的单向传输发送信号
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 int main()
8 {
9 //在fork前创建管道
10 int pipefd[2];//里边有0和1
11 int ret=pipe(pipefd);
12 if(ret==-1)
13 {
14 perror("pipe:");
15 exit(1);
16 }
17 pid_t pid=fork();
18 if(pid>0)
19 {
20 //父进程
21 printf("i am parent process,pid:%d\n",getpid());
25 char buf[1024]={0};
26 while(1)
27 {
28 int len=read(pipefd[0],buf,sizeof(buf));//读取子进程发来的数据
29 printf("parent recv:%s,pid:%d\n",buf,getpid());
34 }
35 }else if(pid==0)
36 { //子进程
37 printf("i am child process,pid:%d\n",getpid());
38 //向父进程发送数据
39 char * str="hello,i am child";
41 while(1)
42 {
43 write(pipefd[1],str,strlen(str));
44 sleep(1);
48 }
49 }
52 return 0;
53 }
输出结果为:
2、制作一个双向传输的代码
在双向通信时一定要注意:子进程和父进程的读写顺序是不一样的,因为子进程要先向父进程发送数据后才能收到由父进程发来的数据,所以对子进程来说是先write(),再read()。而父进程是先接收数据,再给子进程发送数据,所以对父进程来说是先read(),再write(),否则会发生阻塞。
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 int main()
8 {
9 //在fork前创建管道
10 int pipefd[2];//里边有0和1
11 int ret=pipe(pipefd);
12 if(ret==-1)
13 {
14 perror("pipe:");
15 exit(1);
16 }
17 pid_t pid=fork();
18 if(pid>0)
19 {
20 //父进程
21 printf("i am parent process,pid:%d\n",getpid());
22
23 char *strs="i am parent process!";
25 char buf[1024]={0};
26 while(1)
27 {
28 int len=read(pipefd[0],buf,sizeof(buf));//读取来自子进程发来的数据
29 printf("parent recv:%s,pid:%d\n",buf,getpid());
30 //向子进程发送数据
31 write(pipefd[1],strs,strlen(strs));
32 sleep(1);
34 }
35 }else if(pid==0)
36 { //子进程
37 printf("i am child process,pid:%d\n",getpid());
39 char * str="hello,i am child";
40 char buff[1024]={0};
41 while(1)
42 {
38 //向父进程发送数据
43 write(pipefd[1],str,strlen(str));
44 sleep(1);
45 //读取父进程发送来的数据
46 int fd=read(pipefd[0],buff,sizeof(buff));
47 printf("child recv:%s,pid:%d\n",buff,getpid());
48 }
49 }
52 return 0;
53 }
运行结果如下:
觉得好看就给个赞吧,笔芯。