进程间通信常见方式-管道

进程间通信常见方式-管道

学习目标:

掌握进程间通信方式。
掌握管道基本用法。


进程间通信常见方式:

Linux环境下,进程地址空间相互独立,每个进程都有各自的用户地址空间,任何一个进程的全局变量在另一个进程都看不到,所有进程与进程之间不能相互访问,要交换数据必须通过进程,在内核开辟一块缓冲区,将进程数据从用户空间拷贝到内核缓冲区,另一个进程再从内核缓冲区把数据读走,内核提供的该机制称为进程间通信(IPC)。
现今常用的进程间通信方式如下:

  • 管道
  • 信号(开销最小)
  • 共享映射区
  • 本地套接字(最稳定)

管道:

管道:管道是最基本的IPC机制,无名管道只能用于亲缘关系的进程间完成数据传递。调用pipe函数即可创建一个管道,有如下特质:

  • 其本质是一个伪文件(实为内核缓冲区)。
  • 由两个文件描述符引用:一个表示读端,一个表示写端。
  • 规定数据从管道的写端流入管道,从读端流出。

管道的原理:管道实为内核使用环形队列机制,借助内核缓冲区(4K大小)实现。

管道局限性:

  • 数据不能进程自己写,自己读。
  • 管道中的数据不能反复读取,一旦读取,管道中不再存在。
  • 用半双工通信方式,数据只能单方向流动。
  • 亲缘关系进程间可用。

pipe函数:

pipe函数:用于创建一个管道实现进程间通信(头文件 unistd.h) 。函数调用返回R/W两个文件描述符,无需open,需要手动close,其中fd[0] 为读,fd[1]为写。

  1. 父进程调用pipe函数创建管道,得到指向读写两端的两个文件描述符fd[0],fd[1]
  2. 父进程调用fork创建子进程,子进程也有两个文件描述符指向同一管道。
  3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道写入数据,子进程将管道中的数据读出。使用环形队列方式实现,所有数据从写端流入,从读端流出,来实现进程间通信。
    函数原型如下:
int pipe(int pipefd[2]);

参数
pipefd[0]:读端
pipefd[1]:写端
返回值
成功:0
失败: -1 设置errno


管道读写行为:

**读管道**:
  1. 管道有数据:read返回实际读到的字节数。
  2. 管道无数据:
    1. 无写端:read返回0(类似读到文件尾)。
    2. 有写端:read阻塞等待。
    写管道
  3. 无读端:异常终止。(SIGPIPE导致的)
  4. 有读端:
    1. 管道已满:阻塞等待。
    2. 管道未满:返回写出的字节个数。

fifo管道:

fifo管道:用于无亲缘关系的进程间通信。

int mkfifo(const char *pathname,mode_t mode);

参数
pathname:文件路径名。
mode:
- O_RDONLY:只读方式。
- O_WRONLY:只写方式。
- O_NONBLOCK:非阻塞方式。
返回值
成功:0
失败:-1 设置errno。


补充:

文件实现进程间通信:打开的文件是内核中的一块缓冲区。多个无亲缘关系的进程,可以同时访问该文件。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值