Linux进程常见通信方式
创始人
2024-01-28 21:23:17

文章目录

  • 1、管道
    • <1>匿名管道
    • <2> 命名管道
  • 2、共享内存
  • 3、信号量

为什么要进程要进行通信呢?

进程间可能存在特定的协同工作的场景,这个时候就需要一个进程把自己的数据交付给另一个进程,让其进行处理。

进程通信的本质

因为进程具有独立性,那么两个进程要互相通信,必须得先看到同一份资源(一段内存,内存可以以文件方式提供、也可能以队列的方式提供、也可能提供的就是原始的内存块)。进程通信的本质就是,由操作系统参与提供一份所有通信进程都能看到的资源

通信的方式

1、管道

什么是管道

1、管道是Unix中最古老的进程间通信的形式。
2、我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”
在这里插入图片描述

<1>匿名管道

#include
原型 int pipe(int fd[2]);
功能:创建一无名管道
参数 fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0,失败返回错误代码

#include
ssize_t read(int fd, void *buf, size_t count);
功能:从文件描述符中读取数据
参数:fd:文件描述符,buf:目标缓存区, count:期望读取的数据字节大小
返回值:如果成功,则返回读取的字节数(0表示文件结束),读取出错返回-1

ssize_t write(int fd, const void *buf, size_t count);
功能:向文件描述符中写入数据
参数:fd:文件描述符,buf:目标缓存区, count要写入的数据字节大小
返回值:如果成功,则返回写入的字节数(0表示什么都没有写入)。如果出错,返回-1

读写规则

1、如果所有管道写端对应的文件描述符被关闭,则read返回0
2、如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE,进而可能导致write进程退出
3、当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。
4、当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

代码
在这里插入图片描述

运行结果:

在这里插入图片描述

通过上面的3, 4我们可以注意到为啥不是3,5或3,6呢?其实文件描述符的本质就是个数组,因此是有顺序的。

Linux下管道大小

我们可以把上面代码中的29行放开,每次只写一个字符进去,50行读的时间延迟执行就会发现,管道是有大小的,大小为64KB。如下图运行结果:
在这里插入图片描述
上面读写规则中的第三四条也就是因为这个原因。

站在文件描述符角度理解管道

在这里插入图片描述

站在内核角度理解管道

看待管道,就如同看待文件一样!管道的使用和文件一致,迎合了“Linux一切皆文件思想”。

匿名管道特点

1、只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道。
2、管道提供流式服务(面向字节流的)
3、一般而言,进程退出,管道释放,所以管道的生命周期随进程
4、一般而言,内核会对管道操作进行同步与互斥(自带同步互斥)
5、管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道

通信中的四种情况
1.读端不读或读的慢,写端(写满后)要等待读端
2.读端关闭,写端收到SIGPIPE信号直接终止
3.写端不写或写的慢,读端要等写端
4.写端关闭,读端要读完pipe内部的数据然后在读,会读到0表示读到文件结尾。

<2> 命名管道

为了解决匿名管道只能父子通信,引入了命名管道。

命名管道创建

命令行创建

mkfifo filename
在这里插入图片描述
通过程序创建
相关函数:

int mkfifo(const char *filename,mode_t mode)
功能:创建一个特殊文件
参数:filename: 文件名,mode: 权限模式
返回值:成功返回0,失败返回-1

用命名管道实现server&client通信

server
在这里插入图片描述

client

在这里插入图片描述

运行结果:
在这里插入图片描述

命名管道和匿名管道的区别

1、匿名管道由pipe函数创建并打开。
2、命名管道由mkfifo函数创建,打开用open
3、FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

2、共享内存

原理

1、通过调用库函数shmget,在内存中创建一块内存空间。
2、通过调用库函数shmat,让进程 “挂接” 到这块共享内存上。
如图:
在这里插入图片描述
相关函数

功能:用来创建共享内存
原型 int shmget(key_t key, size_t size, int shmflg);
参数:
key:这个共享内存段名字
size:共享内存大小
shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1

shmflg中的
IPC_CREAT:to create a new segment,单独使用或flg为0,创建共享,内存若已存在则返回共享内存
IPC_EXCL : 单独使用没有价值
IPC_CREAT | IPC_EXCL 失败返回-1,若我成功则得到一定是最新共享内存

功能:生成key秘钥
原型:key_t ftok(const char *pathname, int proj_id);
参数:
pathname:路径名, proj_id是子序号,它是一个8bit的整数。即范围是0~255。
返回值:如果成功,将返回生成的key_t值。失败时返回-1

功能:将共享内存段连接到进程地址空间 (attach)
原型 void *shmat(int shmid, const void *shmaddr, int shmflg);
参数 shmid: 共享内存标识 shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1

功能:将共享内存段与当前进程脱离 (detach)
原型 int shmdt(const void *shmaddr);
参数 shmaddr:由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段

功能:用于控制共享内存
原型 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

在这里插入图片描述

用享内存实现server&client通信

server端
在这里插入图片描述

client端
在这里插入图片描述
运行结果:
在这里插入图片描述

3、信号量

什么是信号量

管道,共享内存、消息队列都是以传输数据为目的的。
信号量不是以传输数据为目的的,他是通共享资源的方式来达到多个线程的同步和互斥的目的的。

学习信号量我们要知道的几个概念

1、信号量的本质:是一个计数器,类似 int count;衡量临界资源中资源数目的。
2、什么是临界资源:凡是能够被多个执行流同时能够访问的资源就是临界资源,如管道,共享
内存,消息队列等都是临界资源。
3、什么是临界区:进程代码有很多,其中用来访问临界资源的代码,就叫做临界区。
4、什么是原子性:一件事要么不做,要做就做完,没有中间态,就叫做原子性。
5、什么是互斥:在任意时刻只允许一个执行流进入临界资源,执行它自己的临界区。
6、什么是同步:让访问临界资源的过程在安全的前提下,有一定顺序性。

信号量的代码我们在后面的生产消费者模型中讲解。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
上海有几个区 最新上海16区划... 你平常会使用地图吗?一幅标准的地图可以帮助我们解决很多问题。自然资源部最新公布了长三角标准地图,上海...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
男生摸女生胸 同桌把我带到卧室... 所谓“酒色财气”,酒与色往往是连在一起的,澳洲有个医学生,就因为两次酒后猥亵自己的同学,几乎葬送了自...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...