【Linux下】进程间通信( 二 )


理解协同机制和原子性写入
1.读端读得慢,写端会等待读端读取
验证方法:我们让读端先睡眠20秒,再进行数据读取,写端则每次写入一个字节的内容,而我们会发现,写端写到65536字节时,就会停下来等待读端,而且每次读端至少读走4096字节时,写端才会继续朝管道里继续写入
如图:
可知在.6.11之后的版本下管道大小就是为65536字节
2.读端不读或是直接退出,写端被进程使用13号信号终止
实验方法:写端写入,读端不读或者是直接关闭文件
结果:子进程被系统的信号干掉了
站在os系统的角度: 读端关闭了,而写端还在不断写入,就是在不断的往管道里输入数据,相当于在浪费os的资源;os系统当然会把他干掉
3.写端很慢,读端会等待写端写入
结果就是写端一写数据,读端就会将数据读出来,继续等待写端写入
4.写端关闭,读端read函数读到文件末尾
结果:read函数返回0,代表读到文件末尾,此处即代表子进程写端已经关闭
小总结:
原子性写入
原子性的通俗理解就是:一件事要么不做,要么就一次做完 。例如我们打一桶水一次打完就是原子性的,如果分为俩个半桶就是非原子性的

【Linux下】进程间通信

文章插图
解释:当我们写入的数据少于4096字节时,我们输入是保持原子性写入的,即我们输入的数据会像连着的字符串一样,而当我们写入的数据超过4096字节时,就会采取非原子性写入原则,即我们写入的数据并不会保持连续状,而是会和其他进程输入的数据打乱和其他进程的数据一起放入管道中
小结:
命名管道
特点:
1.以文件形式让毫无关联的进程看到同一份资源
2.命名管道上的数据是不会写入到磁盘里去的,如图:
3.同匿名管道一样,是单向写入的
命名管道创建的俩种方式
一:命令行命令
直接在命令行进行运行该指令,可以直接生成命名管道
也可以在程序中进行命名管道文件写入
二:系统调用接口
参数1:管道文件存放的路径,参数2:管道文件的默认权限,但依然要受我们系统文件掩码的影响
返回值:成功返回0 失败返回-1 并且设置错误码
//创建管道在读写端创建管道文件都可 但是当写端关闭时,会和匿名管道一样 读端read会返回06if(mkfifo(PIPE_NAME,PIPE_commison)<0)7{8perror("mkfifo");9return 1;10}
使用命名管道实现俩个不同进程之间通信
上面我们说过进程通信是需要不同的进程看到一份相同的资源,匿名管道采用的父子进程,子进程继承父进程的里面的实现的不同进程看到同一份资源 。
那么os又是以什么样的方式让俩个进程看到同一个命名管道呢?
而实际上,命名管道让俩个不同的进程看到同一份资源的方法是:路径+文件名(具有唯一标识性)—这也是命名管道为什么要有名字的原因
通过指定路径+文件名(可以唯一的标识该文件),让俩个不相关的进程看到同一个资源,同一块内存,然后进行交互
抽象解释图:
注:管道文件在读写端创建都可
头文件包含:
#pragma once#include #include #include #include #include #include #include #define PIPE_NAME "./fifo"#define PIPE_commison 0666
写端代码:
#include "com.h"int main(){//创建管道在读写端创建管道文件都可 但是当写端关闭时,会和匿名管道一样 读端read会返回0if(mkfifo(PIPE_NAME,PIPE_commison)