Linux进程之间有时需要互相传送消息,Linux为此提供了几种方法,其中之一就是管道。
管道
和日常生活中的一样,管道是单向的,只是里面流动着的是数据。
匿名管道
匿名管道适用于有亲缘关系的进程,从管道的构建形式就能够看出来,可以在Linux shell中键入man 2 pipe
来看一下pipe
这个系统调用的说明,其函数原型为
int pipe(int pipefd[2]);
从这个这个函数原型可以看出,一次调用创建了2个fd,分别是管道的两端,当前进程拿其中一端,另一端就很难给一个不相干的进程了,一般就是给fork出来的一个进程,也就是一个有亲缘关系的进程。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char **argv)
{
int fd[2];
int n;
pid_t pid;
char line[80];
pipe(fd);
pid = fork();
if(pid > 0){
close(fd[0]);
sleep(1);
printf("%d\n", __LINE__);//17
write(fd[1], "hello world\n", 13);
printf("%d\n", __LINE__);//19
sleep(1);
printf("%d\n", __LINE__);//21
write(fd[1], "hello world\n", 13);
printf("%d\n", __LINE__);//23
waitpid(pid,NULL,0);
close(fd[1]);
} else if(pid == 0){
close(fd[1]);
printf("%d\n", __LINE__);//28
n = read(fd[0], line, 80);
printf("%d\n", __LINE__);//29
printf("pipe receive msg: %s", line);
sleep(2);
printf("%d\n", __LINE__);//32
n = read(fd[0], line, 80);
printf("%d\n", __LINE__);//34
close(fd[0]);
exit(0);
}
return 0;
}
输出
28
17
19
30
pipe receive msg: hello world
21
23
33
35
从打印结果可以看出,管道通信成功了,此外还有2点:
- 读的一端是阻塞读,读不到消息不返回;
- 写的一端是非阻塞写。