进程和进程之间的内存是相对独立的
进程和进程通讯原理
进程和进程之间通讯的方式
- 管道(使用最简单)
- 只能用在有血缘关系的进程之中
- 信号(开销最小)
- 共享映射区(无血缘关系)
- 本地套接字(最稳定,实现复杂度最高)
管道
管道必须用在有父子关系的进程中
管道是一种最基本的IPC机制,作用与有血缘关系的进程之间,调用pipe系统函数,即可以创建一个管道,
- 其本质是一个伪文件(实为内核缓存区)
- 由两个文件描述符引用,一个表示读端,一个表示写端
- 规定数据从管道的写入端流入管道,从读取端读出
局限性:
- 自己写,不能自己读
- 数据不可以反复读
- 单工通信
- 血缘关系进程间可用
pipe函数,创建并打开管道
int pipe (int fd[2]);
// 参数
// fd[0] : 读端
// fd[1] : 写端
例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int agrc, char *argv[])
{
int ret;
int fd[2];
pid_t pid;
char buf[1024];
ret = pipe(fd);
if (ret == -1){
sys_err("pipe error");
}
pid = fork();
if (pid>0)
{
close(fd[0]); // 关闭读端
write(fd[1], "hello pipe", strlen("hello pipe"));
close(fd[1]);
// 父进程
} else if(pid==0){
// 子进程
close(fd[1]);
ret = read(fd[0], buf, size(buf));
write(STDOUT_FILENO, buf, ret);
close(fd[0]);
}
return 0;
}
管道的读写行为
读管道
- 管道有数据,read返回实际读到的字节数
- 管道无数据,
- 无写端,read返回0
- 有些端,read堵塞等待
写管道
- 无读端,异常终止
- 有读端,
- 管道已满,阻塞等待
- 管道未满,返回写出的字节个数