IPC--命名/匿名管道通信详解

进程间的通信(IPC)

为什么要提供进程间的通信呢?

因为进程具有独立性,每一个进程都有自己独立的虚拟地址空间,所有的操作都在自己的虚拟地址空间内完成,因此进程之间无法直接通信,所以就有了管道的出现。

如何提供通信方式呢?

给多个进程之间提供一个大家都能够进行访问的传播介质,并且该介质也会根据不同的通信场景提供不同的通信方式,大家就能够进行通信了。

通道:
本质:是内核中的一块缓冲区,若干进程可访问同一块缓冲区,进行通信。
作用:数据传输的资源管道
特点:管道是非覆盖写的数据传输方式。

而管道又分为 匿名管道 和 命名管道。
在这里插入图片描述

匿名管道

匿名管道主要用于具有亲缘关系的进程间的通信(父子进程、兄弟进程)。

特点:
1> 匿名管道是半双工,数据只能向一个方向流动,一端输入,另一端输出。
2> 使用匿名管道时,进程不需要关系管道在内存中位置,但是要通过进程的亲缘关系来实现进程与管道的连接。
3> 管道所传输的数据是无格式的,这要求管道的读写方式必须事先约定好,如多少字节算一个消息等。
4> 管道不是普通的文件,不属于某个系统文件,其只存在于内存中,是不可见文件。
5> 从管道读取数据是一次性操作,数据一旦被读走,它就从管道中被抛弃,释放空间以便于写其他数据。


特性:
1> 若管道中暂无数据,则调用 read 会阻塞。
2> 若管道中数据已满,则调用 write 会阻塞。
3> 若通道中的所有写端 (pipefd[1]) 被关闭,则继续调用 read 会先将管道中的数据全部读取然后返回 0,之后再次调用则会阻塞。
4> 若通道中的所有读端 (pipefd[0]) 被关闭,则继续调用 write 会出现异常并退出。
5> 若管道中从来都没写入过数据,若关闭所有写端,调用 read 会直接返回,不再阻塞; 若仅仅关闭部分写端,调用 read 会阻塞


注意点:
1> 匿名管道一定要创建在子进程之前,这样才能保证子进程能够通过复制父进程得到匿名管道的操作句柄。
2> 父、子进程都具有读写端,因为匿名管道是半双工通信,为了保证进程在运行完后直接退出,而不是继续等待,所以不使用的读写端需要关闭。
3> 一个进程在退出的时候会自动关闭自身的读写端。


创建格式

#include<unistd.h>
int pipe(int pipefd[2])

参数: pipefd[0] --- 用管道读写数据
     pipefd[1] ---  用管道写入数据
     
返回值: 成功 --- 0     失败 --- -1

具体操作使用:

1.父子进程创建并使用匿名管道
在这里插入图片描述
在这里插入图片描述


  1. 用匿名管道实现 ls -l | grep shm
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

命名管道

命名管道又被称为 FIFO,它作为一种特殊的文件类型,在文件系统中有对应的路径。 当一个进程以写 ( w ) 的方式打开,而另一个进程以读 ( r ) 的方式打开该文件,那么内核就能在两个进程之间建立通道。
与匿名管道不同,命名管道是一个可见文件,所以同一主机下的任意进程都可以通过打开该文件实现通信。

特点:
1> 若文件以只读( w ) 打开,则会阻塞,直到该文件被另一个进程以写的方式打开。
2> 若文件以只写( r ) 打开,则会阻塞,直到该文件被另一个进程以读的方式打开。
2> 命名管道严格遵守 ‘ 先进先出 ‘ 原则,当对其进行写操作时,数据会被添加到文件末尾;当对其进行读操作时,文件头部的数据先返回。


特性与匿名管道相同


创建格式:

#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char* path, mode_t mode)
参数: 
    path:  管道文件创建的路径
    mode:  管道的操作权限
返回值:  成功 --- 0     失败 --- -1

具体操作使用:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值