- 第三十八讲 管道
- 一、无名管道(pipe)
- 1、函数介绍
- 2、特点
- 3、使用步骤
- 4、使用示例
- 二、有名管道
- 1、函数介绍
- 2、特点
- 3、使用步骤
- 4、示例
- 读取代码
- 写入代码
- 小提示
| 函数名称 | 函数功能 | 头文件 | 返回值 |
|---|---|---|---|
| int pipe(int pipefd[2]) | 创建无名管道 | unistd.h | 成功:0 失败:-1 |
- 特殊文件,前面说过在 linux 下一切皆文件。而无名管道是一个没有名字的文件,无法使用 open 函数进行操作,但是可以使用 close 函数关闭。
- 只能通过子进程继承文件描述符的形式来使用
- 使用 write 和 read 函数对无名管道进行操作时,可能会阻塞进程
- 所有文件描述符被关闭之后,无名管道被销毁
- 父进程创建无名管道
- 创建子进程
- close 无用端口(单方面传输数据可以这样)
- 读写管道
- 关闭管道描述符
#include二、有名管道 1、函数介绍#include #include #include #include #include int main(void) { pid_t pid; int pipeFd[2]; int status; char readBuf[100]; memset(pipeFd, ' ', sizeof(pipeFd)); if(pipe(pipeFd) < 0) { printf("Create pipe failed!"); return -1; } pid = fork(); if(pid < 0) { printf("Create sub process failed!"); return -1; } if(pid == 0) { close(pipeFd[1]); memset(readBuf, ' ', sizeof(readBuf)); if(read(pipeFd[0], readBuf, sizeof(readBuf)) > 0) { printf("Read data is :%srn", readBuf); } close(pipeFd[0]); exit(0); } if(pid > 0) { close(pipeFd[0]); if(write(pipeFd[1], "hello!sub process!", strlen("hello!sub process!")) < 0) { printf("Write pipe failed!rn"); exit(1); } else { printf("Write pipe success!rn"); close(pipeFd[1]); wait(&status); exit(1); } } return 0; }
| 函数名称 | 函数功能 | 头文件 | 返回值 |
|---|---|---|---|
| int mkfifo(const char *filename, mode_t mode) | 创建有名管道 | sys/types.h sys/stat.h | 成功:0 失败:-1 |
- 有文件名,可以使用 open 函数打开s
- 任意进程间数据传输
- write 和 read 操作可能会阻塞进程
- write 具有"原子性"(会先判断管道内空间是否足以将数据全部写入进去,如果空间足够再去写入管道)
- 创建有名管道(mkfifo)
- 需要传输数据的进程打开有名管道(open),然后读写管道(read/write)
- 操作完关闭管道(close)
#include写入代码#include #include #include #include #include #include #include int main(char *argc, char **argv) { int fd; char readBuf[20]; printf("Fifo read stard!rn"); while(access("my_fifo", F_OK) == -1) { printf("Fifo is not createdrn"); sleep(1); } fd = open("my_fifo", O_RDONLY); if(fd < 0) { printf("Open fifo failed!rn"); exit(0); } memset(readBuf, ' ', sizeof(readBuf)); if(read(fd, readBuf, sizeof(readBuf)) > 0) { printf("Write fifo data is:%srn", readBuf); } close(fd); return 0; }
#include小提示#include #include #include #include #include #include #include int main(char *argc, char **argv) { int fd; if(access("my_fifo", F_OK) == -1) { printf("Fifo is not created, start create fiforn"); if(mkfifo("my_fifo", 0666) < 0) { printf("Create fifo failed!rn"); exit(-1); } printf("Fifo is createdrn"); } fd = open("my_fifo", O_WRONLY); if(fd < 0) { printf("Open fifo failed!rn"); exit(0); } printf("Open fifo success!rn"); if(write(fd, "Hello fifo!rn", strlen("Hello fifo!rn")) <= 0) { printf("Write fifo failed!rn"); exit(-1); } close(fd); return 0; }
细心的朋友可能会发现,在单独执行读或者写管道函数的时候,程序会阻塞在 open 函数。这是因为需要在另一端打开管道函数才能退出阻塞。这个可以通过命令查看 man mkfifo 里面有介绍。这里搬上原文
once you have created a FIFO special file in this way, any process can open it for reading or writing, in the same way as an ordinary file. However, it has to be open at both ends simultaneously before you can proceed to do any input or output operations on it. Opening a FIFO for reading normally blocks until some other process opens the same FIFO for writing, and vice versa. See fifo(7) for nonblocking handling of FIFO special files.



