系统编程-进程间通信-无名管道
管道文件是一个特殊的文件,是由内核环形队列来实现的。
函数形式: int pipe(int fd[2]) ,无需额外调用open,但需手动调用close来关闭fd[0]和fd[1]。
功能: 该系统调用,用于创建无名管道。无名管道作用于有血缘关系的进程之间,完成数据传递。
头文件:#include <unistd.h>
参数:两个文件描述符,fd[0]是读端,fd[1]是写端。
返回值: 成功返回0,出错返回-1。
特点:
** 管道是创建在内存中的,进程结束,空间释放,管道就不存在了。
** 管道中的数据,读完后就被删除了。
** 如果管道中没有数据可读,则会阻塞。
** 如果管道被写满了,也会阻塞。
局限性:
**数据一旦被读走,便不在管道中存在,不可反复读取。
**由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。
**只能在有公共祖先的进程间使用管道。
实验1 - 实现父子进程间通信
实验思路:
1. 父进程调用pipe函数创建无名管道,得到两个文件描述符fd[0]、fd[1]指向管道的读端和写端。
2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。
3. 父进程关闭管道读端,子进程关闭管道写端。(这才是正确操作,只留一个入口,一个出口,这样才能保证数据只在一个方向上流动)
父进程可以向管道中写入数据,子进程将管道中的数据读出。
由于管道是利用环形队列实现的,数据从写端流入管道,从读端流出,这样就实现了进程间通信。
实验代码:
#include <unistd.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <sys/wait.h> void sys_err(const char *str) { perror(str); exit(1); } int main(void) { pid_t pid; char buf[1024]; int fd[2]; char *p = "test for pipe\n"; if (pipe(fd) == -1) sys_err("pipe"); pid = fork(); if (pid < 0) { sys_err("fork err"); }else if (pid == 0) { close(fd[1]); int len = read(fd[0], buf, sizeof(buf)); write(STDOUT_FILENO, buf, len); close(fd[0]); }else { close(fd[0]); write(fd[1], p, strlen(p)); wait(NULL); // 不获取子进程死因,传入NULL即可。 // 父进程一旦调用了wait就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出。 close(fd[1]); } return 0; }
.
/************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/