管道,通常指无名管道。
1、特点:
半双工,具有固定的读端和写端。
只能用于具有亲缘关系的进程间通信。
是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数,但是它并不属于其他任何文件系统,并且只存在于内存中。
从管道中读数据的特点
- 默认用 read 函数从管道中读数据是阻塞的。
- 调用 write 函数向管道里写数据,当缓冲区已满时 write 也会阻塞。
- 通信过程中,读端口全部关闭后,写进程向管道内写数据时,写进程会(收到 SIGPIPE 信号)退出。
2、原型:
#include <unistd.h>
int pipe(int fd[2]); // 返回值:若成功返回0,失败返回-1
当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而打开,要关闭管道只需将这两个文件描述符关闭即可。
3、例子
单个进程中的管道几乎没有任何用处。所以,通常调用 pipe 的进程接着调用 fork,这样就创建了父进程与子进程之间的 IPC 通道。如下图所示:
若要数据流从父进程流向子进程,则关闭父进程的读端(fd[0])与子进程的写端(fd[1]);反之,则可以使数据流从子进程流向父进程。
实例代码:
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int main()
5 {
6 int fd[2]; // 两个文件描述符
7 pid_t pid;
8 char buff[20];
9
10 if(pipe(fd) < 0) // 创建管道
11 printf("Create Pipe Error!\n");
12
13 if((pid = fork()) < 0) // 创建子进程
14 printf("Fork Error!\n");
15 else if(pid > 0) // 父进程
16 {
17 close(fd[0]); // 关闭读端
18 write(fd[1], "hello world\n", 12);
19 }
20 else
21 {
22 close(fd[1]); // 关闭写端
23 read(fd[0], buff, 20);
24 printf("%s", buff);
25 }
26
27 return 0;
28 }