管道(也叫匿名管道),可以在父进程和子进程之间进行通信。管道只能在单一方向上进行数据传输,且只能在父子进程间进行通信,要实现父子间双向数据传输,我们需要两个管道。
管道的创建
管道用函数pipe()
进行创建,其函数原型如下:
1 2
| int pipe(int pipefd[2]);
|
pipe()
函数创建一个管道,管道有两端,pipefd[0]
固定是读取端,pipefd[1]
固定是写入端。
管道的性质
除了只能进行单向数据传输,且只能在父子进程中使用外,管道还有如下这些性质:
- 读和写默认都是阻塞的,对空的管道进行读操作会阻塞进程;同理,对满的管道进行写操作也会阻塞进程;
- 要实现父子间双向的通信,需要至少两个管道;
- 同文件描述符一样,
pipefd[0, 1]
也有计数器。如果pipefd[1]
的计数器为0,再从pipefd[0]
读数据会收到0
表示EOF
;如果pipefd[0]
的计数器为0,那么对pipefd[1]
进行写操作将失败并收到SIGPIPE
信号;
- 一个管道最多只能写入65535字节的数据。
管道在父子进程的通信
父进程在调用fork()
后,之前创建的管道会复制一份给子进程(管道描述符计数器+1),如果我们想要父进程写,子进程读,那么就关闭父进程的pipefd[0]
和子进程的pipefd[1]
;如果希望父进程读,子进程写,那么就关闭父进程的pipefd[1]
和子进程的pipefd[0]
。
下面是一个简单的管道通信的例子(父进程写,子进程读),该例子来源于Linux下的进程通信方式: 管道通信详解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #include <unistd.h> #include <sys/types.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_DATA_LEN 256 #define DELAY_TIME 1 int main() { pid_t pid; int pipe_fd[2]; char buf[MAX_DATA_LEN]; const char data[] = "Pipe Test Program"; int real_read, real_write; memset((void*)buf, 0, sizeof(buf)); if (pipe(pipe_fd) < 0) { printf("pipe create error\n"); exit(1); } if ((pid = fork()) == 0) { close(pipe_fd[1]); sleep(DELAY_TIME * 3); if ((real_read = read(pipe_fd[0], buf, MAX_DATA_LEN)) > 0) { printf("%d bytes read from the pipe is '%s'\n", real_read, buf); } close(pipe_fd[0]); exit(0); } else if (pid > 0) { close(pipe_fd[0]); sleep(DELAY_TIME); if((real_write = write(pipe_fd[1], data, strlen(data))) != -1) { printf("Parent wrote %d bytes : '%s'\n", real_write, data); } close(pipe_fd[1]); waitpid(pid, NULL, 0); exit(0); } return 0; } ———————————————— 版权声明:本文为CSDN博主「好儿郎-志在四方」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https:
|