进程间完成数据传递需要借助操作系统提供的特殊的方法,比如:文件、管道、信号、共享内存、消息队列、套接字、命名管道等。但现在常用的进程间通信方式有:
管道 – 使用最简单
pipe
管道一般读写行为
FIFO(有名管道):
用于非血缘关系进程间通信
信号 – 开销最小
共享映射区 – 无血缘关系
nmap
函数的参数使用注意事项
用于非血缘关系进程间的通信
本地套接字 – 最稳定
Linux下其中文件类型
- 文件
d 目录
l 符号链接
伪文件:
s 套接字
b 块设备
c 字符设备
p 管道
其中文件、目录、符号链接是占用磁盘存储的。
管道:
- 本质是一个伪文件
- 由两个文件描述符引进,一个表示读端,一个表示写端。
- 规定数据从管道的写端流入管道,从读端流出。
管道的原理:管道实为内核使用环形队列机制,借助内核缓冲区(4K)实现。
管道的局限性:
- 数据自己读不能自己写
- 数据一旦被读走,就不在管道中存在,不可反复读取。
- 由于管道采用半双工方式,因此,数据只能在一个方向上流动。
- 只能在由公共祖先的进程间使用管道。
pipe()函数实现管道通信:
/*** pipe.c ***/ #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h>int main() {int fd[2];pid_t pid;int ret = pipe(fd);if(-1 == ret){perror("pipe error:");exit(1);}pid = fork();if(-1 == pid){perror("pipe error:");exit(1);}else if(0 == pid) //son process read {close(fd[1]);char buf[1024];ret = read(fd[0],buf,sizeof(buf));if(0 == ret){printf("ret = %d\n",ret);}write(STDOUT_FILENO,buf,ret);}else //father process write {sleep(1);close(fd[0]);write(fd[1],"hello pipe\n",strlen("hello pipe\n"));}return 0; }