五、进程间通信-无名管道
1、无名管道
用于具有亲缘关系的进程间通信(常见的就是父子进程),数据只能单向流动。
(1)创建管道
1 | #include<unistd.h> <br>int pipe(int pipefd[2]); |
参数:
- pipefd[2]:参数为两个文件描述符,一个读文件描述符,一个写文件描述符。
返回值:
- 成功返回0
- 失败返回-1,且errno错误码被设置。
(2)特点:
-
特殊文件(没有名字),无法使用open,但是可以使用close.
-
只能通过子进程继承文件描述符的形式来使用。
-
write和read操作可能会zuse进程。
-
所有文件描述符被关闭之后,无名管道被销毁。
(3)使用步骤
-
父进程pipe无名管道
-
fork子进程。
-
close无用端口。
-
write/read读写端口。
-
close读写端口。
(4)应用实例
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 60 61 62 63 | #include<unistd.h> #include<stdio.h> #include<string.h> #include<stdlib.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) { /*子进程关闭写文件描述符,并通过使子进程暂停3s等待父进程已关闭相应的读描述符*/ 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) { /*关闭父进程读描述符,并通过使父进程暂停1s等待子进程已关闭相应的写描述符*/ close(pipe_fd[0]); sleep(DELAY_TIME); if ((real_write == write(pipe_fd[1],data, strlen (data)))!= -1) { printf ( "Parent write %d bytes:'%s'\n" ,real_write,data);; } /*关闭父进程写描述符*/ close(pipe_fd[1]); /*收集子进程退出信息*/ waitpid(pid,NULL,0); exit (0); } return 0; } |
-
定义一个数组pipe_fd,在创建匿名管道后通过数组返回管道的文件描述符。
-
调用pipe()创建一个匿名管道,创建成功则得到两个文件描述符pipe_fd[0]、 pipe_fd[1],否则返回-1。
-
调用fork()创建一个子进程,如果返回值是0则表示此时运行的是子进程,那么在子进程中调用close()函数关闭写描述符,并使子进程睡眠3s等待父进程已关闭相应的读描述符。
-
子进程调用read()函数读取管道内容,如果管道没有数据则子进程将被阻塞,读取到数据就将数据打印出来。特别地如果调用read()函数读取一个关闭了写描述符的管道,那么read()会返回0,(本例子中父进程的写描述符没有关闭)。
-
调用close()函数关闭子进程读描述符。
-
如果fork()函数的返回值大于0,则表示此时运行的是父进程,那么在父进程中先调用close()关闭管道的读描述符,并且等待1s,因为此时可能子进程先于父进程运行,暂且.等待一会。
-
父进程调用write()函数将数据写入管道。
-
关闭父进程写描述符。
-
调用waitpid()函数收集子进程退出信息并退出进程。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具