进程间通信的五种方式

2023-05-16

进程间通信的意思就是在不同进程之间传递信息。它是一组编程接口,让程序员协调不同进程,使能够相互传递消息。

IPC目的

1)数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间。

2)共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。

3)通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。

4)资源共享:多个进程之间共享同样的资源。为了作到这一点,需要内核提供锁和同步机制。

5)进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

IPC方式包括:管道、系统IPC(信号量、消息队列、共享内存)和套接字(socket)。

管道:

3种。管道是面向字节流,自带互斥与同步机制,生命周期随进程。 

1)普通管道PIPE, 通常有两种限制,一是半双工,数据同时只能单向传输;二是只能在父子或者兄弟进程间使用.,

2)命令流管道s_pipe: 去除了第一种限制,为全双工,可以同时双向传输,

3)命名管道FIFO, 去除了第二种限制,可以在许多并不相关的进程之间进行通讯。

①无名管道:没有磁盘节点,仅仅作为一个内存对象,用完就销毁了。因此没有显示的打开过程,实际在创建时自动打开,并且生成内存iNode,其内存对象和普通文件的一致,所以读写操作用的同样的接口,但是专用的。因为不能显式打开(没有任何标示),所以只能用在父子进程,兄弟进程, 或者其他继承了祖先进程的管道文件对象的两个进程间使用【具有共同祖先的进程】

int pipe(int fd[2]);//由参数fd返回两个文件描述符,fd[0]为读而打开  fd[1]为写而打开

int read(fd[0], buff, int size);    int write(fd[1], buff, int size);

②有名管道:任意两个或多个进程间通讯。因为它在文件目录树中有一个文件标示(FIFO) 实际不占据磁盘空间,数据缓存在内存上。它与普通文件类似,都遵循打开,读,写,关闭的过程,但读写的内部实现和普通文件不同,和无名管道一样。

命令:mkfifo a=filename  //mkfifo(char *path,int flag)系统调用。

标识符与键:每个内核的IPC结构(消息队列、信号量或共享内存)都用一个非负整数标识符引用。

标识符是IPC对象的内部名。为了是多个进程间能够访问到同一IPC对象,需要提供一个外部名。即“键(key)”,键与每个IPC对象关联,并作为对象的外部名。键的数据类型为key_t,由内核变换成标识符。

内核对象:用于进程间通讯时,多进程能访问同一资源的记录,用标识符标识。。

                                 

信号量:

              1.临界资源:同一时刻,只能被一个进程访问的资源

               2.临界区:访问临界资源的代码区

              3.原子操作:任何情况下不能被打断的操作。

            它是一个计数器,记录资源能被多少个进程同时访问。用于控制多进程对临界资源的访问(同步)),并且是非负值。主要作为进程间以及同一进程的不同线程间的同步手段。

操作:创建或获取,若是创建必须初始化,否则不用初始化。

      int semget((key_t)key, int nsems, int flag);//创建或获取信号量

      int semop(int semid, stuct sembuf*buf, int length);//加一操作(V操作):释放资源;减一操作(P操作):获取资源

      int semct(int semid, int pos, int cmd);//初始化和删除

注:我们可以封装成库,实现信号量的创建或初始化,p操作,V操作,删除操作。。

消息队列:

        消息队列是消息的链表,是存放在内核中并由消息队列标识符标识。因此是随内核持续的,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区受限等特点。允许不同进程将格式化的数据流以消息队列形式发送给任意进程,对消息队列具有操作权限的进程都可以使用msgget完成对消息队列的操作控制,通过使用消息类型,进程可以按顺序读信息,或为消息安排优先级顺序。

          与信号量相比,都以内核对象确保多进程访问同一消息队列。但消息队列发送实际数据,信号量进行进程同步控制。

         与管道相比,管道发送的数据没有类型,读取数据端无差别从管道中按照前后顺序读取;消息队列有类型,读端可以根据数据类型读取特定的数据。

         操作:创建或获取消息队列, int msgget((key_tkey, int flag);//若存在获取,否则创建它

        发送消息:int msgsnd(int msgid, void *ptr, size_t size, int flag); ptr指向一个结构体存放类型和数据 size 数据的大小

        接受消息:int msgrcv(int msgid, void *ptr, size_t size, long type, int flag);

        删除消息队列: int msgctl(int msgid, int cmd, struct msgid_ds*buff);

共享内存:

       共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。

        共享内存是最快的一种IPC,因为不需要在客户进程和服务器进程之间赋值。使用共享内存的唯一注意的是是多个进程对一给定的存储区的同步访问。【若服务器进程正在向共享存储区写入数据,则写完数据之前客户进程不应读取数据,或者客户进程正在从共享内存中读取数据,服务进程不应写入数据。。所以我们要对共享内存进行同步控制,通常是信号量。】

int shmget((key_t)key, size_t size, int flag); //size 开辟内存空间的大小,flag:若存在则获取,否则创建共享内存存储段,返回一个标识符。

void *shmat(int shmid, void *addr, int flag); //将共享内存段连接到进程的地址空间中,返回一个共享内存首地址

       函数shmat将标识号为shmid共享内存映射到调用进程的地址空间中,映射的地址由参数shmaddr和shmflg共同确定,其准则为:

       (1) 如果参数shmaddr取值为NULL,系统将自动确定共享内存链接到进程空间的首地址。

       (2) 如果参数shmaddr取值不为NULL且参数shmflg没有指定SHM_RND标志,系统将运用地址shmaddr链接共享内存。

       (3) 如果参数shmaddr取值不为NULL且参数shmflg指定了SHM_RND标志位,系统将地址shmaddr对齐后链接共享内存。其中选项SHM_RND的意思是取整对齐,常数SHMLBA代表了低边界地址的倍数,公式“shmaddr – (shmaddr % SHMLBA)”的意思是将地址shmaddr移动到低边界地址的整数倍上。

int shmdt(void *ptr); //断开进程与共享内存的链接

         进程脱离共享内存区后,数据结构 shmid_ds 中的 shm_nattch 就会减 1 。但是共享段内存依然存在,只有 shm_attch 为 0 后,即没有任何进程再使用该共享内存区,共享内存区才在内核中被删除。一般来说,当一个进程终止时,它所附加的共享内存区都会自动脱离。

int shmctl(int shmid, int cmd, struct shmid_ds *buff); //删除共享内存(内核对象)

       shmid是shmget返回的标识符;

      cmd是执行的操作:有三种值,一般为 IPC_RMID  删除共享内存段;

      buff默认为0.

      如果共享内存已经与所有访问它的进程断开了连接,则调用IPC_RMID子命令后,系统将立即删除共享内存的标识符,并删除该共享内存区,以及所有相关的数据结构;

       如果仍有别的进程与该共享内存保持连接,则调用IPC_RMID子命令后,该共享内存并不会被立即从系统中删除,而是被设置为IPC_PRIVATE状态,并被标记为”已被删除”(使用ipcs命令可以看到dest字段);直到已有连接全部断开,该共享内存才会最终从系统中消失。

        需要说明的是:一旦通过shmctl对共享内存进行了删除操作,则该共享内存将不能再接受任何新的连接,即使它依然存在于系统中!所以,可以确知, 在对共享内存删除之后不可能再有新的连接,则执行删除操作是安全的;否则,在删除操作之后如仍有新的连接发生,则这些连接都将可能失败!

消息队列和管道基本上都是4次拷贝,而共享内存(mmap, shmget)只有两次。

     4次:1,由用户空间的buf中将数据拷贝到内核中。2,内核将数据拷贝到内存中。3,内存到内核。4,内核到用户空间的buf.

     2次: 1,用户空间到内存。 2,内存到用户空间。

        消息队列、共享内存和管道都是内核对象,所执行的操作也都是系统调用,而这些数据最终是要存储在内存中执行的。因此不可避免的要经过4次数据的拷贝。但是共享内存不同,当执行mmap或者shmget时,会在内存中开辟空间,然后再将这块空间映射到用户进程的虚拟地址空间中,即返回值为一个指向逻辑地址的指针。当用户使用这个指针时,例如赋值操作,会引起一个从逻辑地址到物理地址的转化,会将数据直接写入对应的物理内存中,省去了拷贝到内核中的过程。当读取数据时,也是类似的过程,因此总共有两次数据拷贝。

socket通信

       适合同一主机的不同进程间和不同主机的进程间进行全双工网络通信。但并不只是Linux有,在所有提供了TCP/IP协议栈的操作系统中几乎都提供了socket,而所有这样操作系统,对套接字的编程方法几乎是完全一样的,即“网络编程”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

进程间通信的五种方式 的相关文章

  • windows下clion配置cmake

    1 Cmake安装 cmake官方链接 进入cmake官网下载cmake xff0c 然后一路next xff0c 傻瓜式安装 2 MinGW安装 MinGW官网安装 xff0c 或者去其他论坛找资源 然后打开桌面的快捷方式 xff0c 没
  • ubuntu18.04 安装 roboware-studio

    RoboWare Studio是一个ROS集成开发环境 与ROS匹配性比起其他IDE更好 xff0c 可以用它开发 ROS更加简单 并且在官网ros wiki中有详细的使用教程 本文主要是在Ubuntu18 04中安装RoboWare St
  • 烧录工具Android Tool的使用

    RK3308 该工具是RK的开发工具 xff0c 用于烧录用的 xff0c 不同型号的芯片对应的Android Tool中的下载镜像界面也不一样 xff0c 你像RK3308编出来的烧录文件有如下 xff1a 对应的Android Tool
  • Jetson nano i2c教程(MPU6050 + PCA9685)

    首先介绍nano板子上的i2c相关的硬件信息 xff1a 安装所需要的i2c库 sudo apt get install l y i2c tools 完成nano中io与i2c设备的硬件接线 本次案例使用的是PCA9685和MPU6050
  • ROS中发布里程计消息(Odometry)

    目录 1 首先理解里程计是什么 xff1f 2 里程计发布流程3 发布里程计TF变换2 1c 43 43 发布TF变换2 2 python发布TF变换 根据阿克曼转向结构的车辆实现里程计消息的发布 xff0c 本文参考博客如下 xff0c
  • ROS std_msgs/Header 数据含义

    std msgs Header msg消息里数据主要有一下几部分 xff1a uint32 seq time stamp string frame id 分别对这些数据做一个介绍 xff0c 如有错误 xff0c 欢迎批评指正 xff01
  • Carsim中添加路径

    目录 1 新建3D Road 数据库2 设置具体参数3 添加自定义道路信息 利用carsim和simulink联合仿真时 xff0c 需要给定参考轨迹 xff0c 具体设置如下 xff1a 1 新建3D Road 数据库 在Miscella
  • Carsim 2019 Run Now 按钮灰色

    安装carsim后 xff0c Run control with Simulink 模块中的Run Now 和Send to simulink 按钮灰色如下图所示 xff1a 解决办法 xff1a 在License Setting中 xff
  • Ubuntu 添加串口权限

    ubuntu串口添加权限方法 Ubuntu 添加串口权限前言一 添加用户组 xff0c 可长期使用二 给当前终端权限 xff08 单次有效 xff09 1 指定串口2 通用 三 修改文件 Ubuntu 添加串口权限 提示 xff1a 文章写
  • Ubuntu 虚拟机右上角网络连接符号消失

    这里写自定义目录标题 Ubuntu 虚拟机右上角网络连接符号消失解决方案 xff1a Ubuntu 虚拟机右上角网络连接符号消失 Ubuntu 虚拟机右上角网络连接符号消失 xff0c 如下图所示 解决方案 xff1a span class
  • C/C++中局部变量static用法实例

    1 普通局部变量存储于进程栈空间 xff0c 使用完毕会立即释放 xff0c 静态局部变量使用static修饰符定义 xff0c 即使在声明时未赋初值 xff0c 编译器也会把它初始化为0 xff0c 并且静态局部变量存储于进程的全局数据区
  • 嵌入式C语言经典面试题(一)

    1 用预处理指令 define 声明一个常数 xff0c 用以表明1年中有多少秒 xff08 忽略闰年问题 xff09 define SECONDS PER YEAR 60 60 24 365 UL 我在这想看到几件事情 xff1a 1 d
  • 更新Ubuntu内核到最新版本

    想起自己多年前玩Linux的时候知道了两个命令 xff1a sudo apt get update sudo apt get upgrade 以为是能够更新所有软件的 xff0c 后来发现 系统还是不能够更新的 那么 xff0c 系统应该如
  • RK3308 按键Key与LED灯

    硬件原理图 LED指示灯 麦克风阵列子板上使用12颗RGB灯作为效果指示灯 用户可以通过I2C总线配置LED灯驱动IC来是实现不同场景下的灯效 按键Key 麦克风阵列子板上集成五个控制按键 xff0c 分别为 xff1a 控制音量增减的VO
  • if选择结构

    if单选择结构 if双选择结构 if多选择结构 span class token keyword if span span class token punctuation span score span class token operat
  • Windows10下Eclipse+Python环境配置与新项目创建

    最近心血来潮 xff0c 突然想学一下python xff0c 按理说应该不用Eclipse xff0c 但是一想以后还可能会用Java xff0c 那还是装这个 xff0c 然后配置一下环境吧 xff0c 其中也有很多坑 xff0c 希望
  • 理解地址空间和逻辑地址生成

    1 1 地址空间 物理地址 xff1a 硬件 例如内存条 所支持地址空间 xff0c 地址空间的管理由硬件完成 逻辑地址 虚拟地址 xff1a 运行地址所看到的地址空间 xff0c 地址空间是一维的 xff0c 应用程序更加容易访问和管理
  • QT DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x800c000d ()

    使用QT播放音频的时候出现如下错误 DirectShowPlayerService doSetUrlSource Unresolved error code 0x800c000d 原因是url错误
  • 3种蓝牙架构实现方案(蓝牙协议栈方案)

    导言 不同的蓝牙架构可以用在不同的场景中 从而协议帧的架构方案也会不同 转载自 xff1a https www cnblogs com schips p 12293141 html 三种蓝牙架构实现方案 xff08 蓝牙协议栈方案 xff0

随机推荐

  • 驱动遍历句柄表

    xfeff xfeff 驱动遍历句柄表附加第二个方法的反汇编代码 其中还有对其拦截的方式的一些需要HOOK处比如伪造句柄表 因为大量使用硬编码所以此份代码通用性不强一切均在虚拟机XP3下操作 include 34 ntddk h 34 ty
  • Javascript案例:猜数字游戏

    要求 程序随机生成一个1 10之间的数字 xff0c 并让用户输入一个数字 如果大于该数字 xff0c 就提示 xff0c 数字大了 xff0c 继续猜如果小于该数字 xff0c 就提示 xff0c 数字小了 xff0c 继续猜如果等于该数
  • 操作系统之进程 (五) --- 进程、进程实体、PCB...

    文章目录 进程什么叫进程什么叫进程实体进程与进程实体的关系PCB的存储信息与分类 进程的组织方式链接方式索引方式 进程的特征总结感谢 进程 什么叫进程 进程和程序差不多 xff0c 他们有所联系也有所区别 我们以我们熟悉的程序入手 xff0
  • 如何让树莓派默认启动进入图形界面

    设置Raspbian图形启动 当你第一次安装Raspbian系统时 xff0c 确实有一些选项需要你来配置 xff0c 由于匆忙 xff0c 我没有注意到这些 xff0c 只是快速完成屏幕上的选项 如果你遇到了和我一样的情况 xff0c 最
  • ROS与stm32通信

    0 概述 ros和stm32等嵌入式单片机的最大区别在于ros主要用于处理slam 机器视觉 人工智能这种对于算力要求高 xff0c 算法复杂的问题 xff1b 而stm32和arduino等主要用来处理一些边缘事件 xff0c 比如亮个L
  • 硬件仪器的使用

    示波器的使用 用于红外捕捉 xff0c 一开始可以把探头扣在探头补偿的位置 xff0c 显示出一个正常的方波信号5V 1KHz 按下CH1的菜单 xff0c 能够弹出右边的选项 xff0c 注意设置为直流和10X电压 按下触发处的Menu菜
  • pytorch显存越来越多的一个潜在原因-- 这个函数还没有在torch.cuda.Tensor中定义

    最近在用pytorch跑实验 xff0c 有如下操作需要用到 xff08 pytorch版本为0 3 1 xff09 class SpatialFilter nn Module def init self mode 61 True sf r
  • KPI异常检测【一】- 时间序列分解算法

    目录 1 相关概念 2 常见的时间序列 3 时间序列分解 3 1 方法介绍 3 2 经典方法 3 3 Holt Winter 指数平滑 3 4 STL分解 4 异常准则 5 异常检测算法 1 相关概念 1 1 异常 时序异常检测通常形式化为
  • KPI异常检测【三】- 机器学习算法

    目录 1 相关概念 1 1 异常类型 1 2 检测方法 2 点异常检测算法 2 1 基于统计 2 2 基于相似度 2 2 1 基于距离 2 2 2 基于密度 2 2 3 基于聚类 2 2 4 基于树 2 3 基于谱 spectral 3 上
  • 手把手教你如何安装ROS+Gazebo+PX4开发环境(ubuntu18.04 + Melodic)

    参考PX4官网 xff0c 做如下总结 xff1a 1 安装 Ubuntu 43 ROS 步骤省略 xff0c 提前配置好梯子 xff0c 很多安装问题都是网络原因引起的 2 下载并安装PX4源码 git clone https githu
  • ROS+Gazebo+PX4仿真步骤

    本文参考链接 xff1a 入门教程 PX4 Gazebo仿真 知乎 zhihu com 1 参照上一个帖子 手把手教你如何安装ROS 43 Gazebo 43 PX4开发环境 xff08 ubuntu18 04 43 Melodic xff
  • ROS+Gazabo+PX4仿真学习常用网站记录

    1 PX4官网 xff1a PX4 User Guide 中文网站 xff1a https docs px4 io master zh ros mavros custom messages html 2 ROS Wiki xff1a cn
  • 如何订阅(Subscribe)现有功能包节点的话题,介绍实现思路

    我们从github或其他途径获取到的ROS功能包 xff0c 如何快速的加入到自己的工程里边 xff0c 下边介绍一下我实现的思路 1 首先运行功能包 xff0c 利用 rqt graph 命令查看 节点图 xff0c 对功能包的节点和话题
  • PX4仿真时,如何在Gazebo下添加物理环境

    1 安装Gazebo xff0c 步骤略 2 下载安装Gazebo需要的世界模型 xff0c 否则自动安装速度很慢 3 在Ubuntu终端里输入 gazebo xff0c 打开一个空的 Gazebo 界面 4 点击左上方的 insert x
  • 树莓派如何使用串口,树莓派连接pixhawk

    参考链接 xff1a xff08 写的非常详细 xff0c 下述方法亲测有效 xff09 pi 3 How do I make serial work on the Raspberry Pi3 PiZeroW Pi4 or later mo
  • 树莓派备份系统

    使用 rpi backup 脚本进行备份 首先下载该脚本 xff1a git clone https github com nanhantianyi rpi backup git cd rpi backup 用法 xff1a sudo ba
  • Linux和Windows可执行文件的区分

    一些后缀区分 现在PC平台流行的可执行文件格式 xff08 Executable xff09 xff0c 主要有以下两种格式 xff08 COFF xff08 Common file format xff09 格式的变种 xff09 xff
  • 树莓派+ubuntu18.04+ROS-melodic+MAVROS+librealsense+vio+realsense_ros

    目录 一 树莓派安装ubuntu18 04 1 下载ubuntu系统文件 2 将系统文件烧入SD卡 3 强制修改HDMI输出分辨率 xff08 此步骤可忽略 xff09 4 设置wifi xff08 此步骤也可忽略 xff0c 后续连接网线
  • APM+Gazebo 垂起固定翼VTOL软件在环仿真

    APM 43 Gazebo 垂起固定翼VTOL软件在环仿真 1 APM软件环境下载并安装APM固件加入环境变量 2 运行APM仿真3 Gazebo环境安装4 增加VTOL模型5 多机仿真6 使用mavros 1 APM软件环境 参考官网链接
  • 进程间通信的五种方式

    进程间通信的意思就是在不同进程之间传递信息 它是一组编程接口 xff0c 让程序员协调不同进程 xff0c 使能够相互传递消息 IPC目的 1 xff09 数据传输 xff1a 一个进程需要将它的数据发送给另一个进程 xff0c 发送的数据