进程间通信(IPC)的几种方式

进程间通信(IPC)

  • 1.常见的通信方式
  • 2.低级IPC方法
    • 文件
  • 3.常用于本机的IPC机制
    • 3.1无名管道pipe
    • 3.2命名管道FIFO
    • 3.3消息队列MessageQueue
    • 3.4共享内存SharedMemory
    • 3.5信号量Semaphore
    • 3.6信号Signal
    • 3.7unix域套接字
  • 4.不同计算机上的IPC机制
  • 5.IPC机制的数据拷贝次数

1.常见的通信方式

  1. 文件:进程间可以经由fork,exec以及文件系统传送文件。
  2. 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
  3. 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
  4. 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  5. 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
  6. 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  7. 信号Signal : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
  8. unix域套接字:unix域套接字用于在同一台计算机上运行的进程之间的通信,其可以在两个进程间传送打开文件描述符。
  9. 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

2.低级IPC方法

文件

进程间通信可以通过传送打开文件(fork,exec与文件系统)来实现,不同的进程通过一个或多个文件来传递信息,事实上,在很多应用系统里,都使用了这种方法。但一般说来,进程间通信不包括这种似乎比较低级的通信方法。

3.常用于本机的IPC机制

3.1无名管道pipe

特点:
无名管道是半双工的即数据只能在一个方向上流动),具有固定的读端和写端

因为没有名字,因此无名管道只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

无名管道只存在于内存中,其实质是一个内核缓冲区。进程以先进先出的方式从缓冲区存取数据:管道一端的进程顺序地将进程数据写入缓冲区,另一端的进程则顺序地读取数据。

无名管道由pipe()函数创建:

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

参数filedis返回两个文件描述符:filedes[0]为读而打开,filedes[1]为写而打开。filedes[1]的输出是filedes[0]的输入。

3.2命名管道FIFO

命名管道和无名管道的主要区别在于,命名管道有一个文件名字,这个文件名对应于一个磁盘索引节点,有了这个文件名,任何进程有相应的权限都可以对它进行访问

Linux中通过系统调用mknod()或makefifo()来创建一个命名管道。

mkfifo myfifo
mknod myfifo p

3.3消息队列MessageQueue

消息队列与管道通信相比,其优势在于接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息

3.4共享内存SharedMemory

共享内存机制其允许两个或多个进程共享一个给定的存储区,这一段存储区可以被两个或两个以上的进程映射至自身的地址空间中,一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取错做读出,从而实现了进程间的通信。

采用共享内存进行通信的一个主要好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝,对于像管道和消息队里等通信方式,则需要再内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次:一次从输入文件到共享内存区,另一次从共享内存到输出文件。
在这里插入图片描述

3.5信号量Semaphore

信号量(semaphore)与已经介绍过的 IPC 结构不同,它是一个计数器。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据

特点

  1. 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。
  2. 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。
  3. 每次对信号量的PV 操作不仅限于对信号量值减1或加1,而且可以加减任意正整数。

P操作:信号量的值减1,若信号量的值减1后小于0,则该进程被阻塞后放入等待该信号量的等待队列中
V操作:信号量的值加1,若信号量的值加1后的结果小于或等于0,则从该信号的等待队列中释放一个等待进程

3.6信号Signal

内核进程利用信号来通知用户进程发生了哪些系统事件,用户进程对信号的响应方式如下:

  1. 忽略信号:对信号不做任何处理,但是有两个信号不能忽略:即SIGKILL及SIGSTOP。
  2. 捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数。但是有两个信号不能捕获:即SIGKILL及SIGSTOP。
  3. 执行缺省操作:Linux对每种信号都规定了默认操作。

3.7unix域套接字

Unix域套接字用于同一台pc上运行的进程之间通信它仅仅复制数据,不执行协议处理(比如增加删除网络报头,计算校验和,产生顺序号,发送确认报文),因此Unix域套接字往往比通信两端位于同一主机的TCP套接字要快

4.不同计算机上的IPC机制

套接字Socket
套接口(socket)编程是实现不同计算机中进程间通信的主要方式之一。我们熟知的WWW服务、FTP服务、TELNET服务等都是基于套接口编程来实现的。除了在异地的计算机进程间以外,套接口同样适用于本地同一台计算机内部的进程间通信。

5.IPC机制的数据拷贝次数

共享内存是最高效的进程间通信的方式,因为把同一块物理内存的地址空间映射到不同进程的地址空间当中,那么不同的进程之间通信,通过直接修改地址空间当中的内存即可,该机制的实现只需要两次拷贝即可实现,即数据从用户空间到内存,数据再从内存到用户空间。

其它的进程通信机制需要四次拷贝操作。假设现在A和B间需要通信,首先从进程A的缓冲区中将数据拷贝到内核中,其次内核将数据拷贝到内存中,之后数据又从内存被拷贝到内核,最后内核将数据拷贝到进程B的缓冲区中。因此使用共享内存通信比较高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/71586.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用友-NC-Cloud远程代码执行漏洞[2023-HW]

用友-NC-Cloud远程代码执行漏洞[2023-HW] 一、漏洞介绍二、资产搜索三、漏洞复现PoC小龙POC检测脚本: 四、修复建议 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#…

网络防御之SSL VPN

1. SSL工作过程是什么&#xff1f; 第一阶段&#xff1a; 客户端发送client hello消息到服务端&#xff0c;服务端收到client hello消息后&#xff0c;再发送server hello消息到客户端。 第二阶段&#xff1a; 服务器的证书&#xff0c;用于客户端给客户端发送信息时加密 serv…

最新智能AI系统+ChatGPT源码搭建部署详细教程+知识库+附程序源码

近期有网友问宝塔如何搭建部署AI创作ChatGPT&#xff0c;小编这里写一个详细图文教程吧。 使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到AIGC系统&#xff01; 增加手机端签到功能、优化后台总计绘画数量逻辑&#xff01;新增 MJ 官方图片重新生成指令功能同步官方 …

Apollo让自动驾驶如此简单

前言&#xff1a; 最近被新能源的电价闹的不行&#xff0c;买了电车的直呼上当了、不香了。但电车吸引人不只是公里油耗低&#xff0c;还有良好的驾车使用感。比如辅助驾驶、甚至是自动驾驶。今天来介绍一个头部自动驾驶平台Apollo&#xff0c;Apollo是一个开源的、自动驾驶的软…

mac安装vscode 配置git

1、安装vscode 官网地址 下载mac稳定版安装很慢的解决办法 (转自) mac电脑如何解决下载vscode慢的问题 选择谷歌浏览器右上角的3个点&#xff0c;选择下载内容&#xff0c;右键选择复制链接地址&#xff0c;在新窗口粘贴地址&#xff0c; 把地址中的一段替换成下面的vscode.cd…

06_Hudi案例实战

本文来自"黑马程序员"hudi课程 6.第六章 Hudi案例实战 6.1 案例架构 6.2 业务数据 6.2.1 消息数据格式 6.2.2 数据生成 6.3 七陌数据采集 6.3.1 Apache Flume 是什么 6.3.2 Apache Flume 运行机制 6.3.3 Apache Flume 安装部署 6.3.4 Apache Flume 入门程序 6.3.5 七…

Linux 终端命令之文件浏览(3) less

Linux 文件浏览命令 cat, more, less, head, tail&#xff0c;此五个文件浏览类的命令皆为外部命令。 hannHannYang:~$ which cat /usr/bin/cat hannHannYang:~$ which more /usr/bin/more hannHannYang:~$ which less /usr/bin/less hannHannYang:~$ which head /usr/bin/he…

linux I/O性能优化

Linux 文件系统 磁盘和文件系统的关系&#xff1a; 磁盘为系统提供了最基本的持久化存储。 文件系统则在磁盘的基础上&#xff0c;提供了一个用来管理文件的树状结构。 文件系统工作原理 索引节点和目录项 文件系统&#xff0c;本身是对存储设备上的文件&#xff0c;进行组织…

cesium学习记录07-实体(Entity)

在学习记录05中&#xff0c;我们将了如何在 Cesium 中加载各种数据&#xff0c;包括矢量数据、影像图层、地形和 3D 模型。这些数据为我们构建了一个基础的场景和背景。特别是在加载 3D 模型时&#xff0c;我们采用了 viewer.scene.primitives.add 方法将模型作为一个原始对象添…

chatGPT小白快速入门-002:一文看懂什么是chatGPT

一、前言 本文是《chatGPT小白快速入门培训课程》的第002篇文章&#xff1a;一文看懂什么是chatGPT&#xff0c;全部内容采用chatGPT和chatGPT开源平替软件生成。完整内容大纲详见&#xff1a;《chatGPT小白快速入门课程大纲》。 本系列文章&#xff0c;参与&#xff1a; AIGC…

【STM32】FreeRTOS消息队列和信号量学习

一、消息队列&#xff08;queue&#xff09; 队列是一种用于实现任务与任务之间&#xff0c;任务与中断之间消息交流的机制。 注意&#xff1a;1.数据的操作是FIFO模式。 2.队列需要明确数据的大小和队列的长度。 3.写和读都会出现堵塞。 实验&#xff1a;创建一个消息队列…

阿里云弹性裸金属服务器详细介绍(原神龙)

阿里云弹性裸金属服务器&#xff08;ECS Bare Metal Server&#xff09;是一种可弹性伸缩的高性能计算服务&#xff0c;原神龙服务器&#xff0c;计算性能与传统物理机无差别&#xff0c;具有安全物理隔离的特点&#xff0c;裸金属服务器分钟级的交付周期。阿里云服务器网分享阿…

python——案例18:判断该元素是否在列表中

案例18&#xff1a;判断该元素是否在列表中test_list[10,-8,25.6,88,0,4]print("查看88是否在列表里面&#xff1a;")for i in test_list:if(i88):print("存在") print("查看88是否在列表中&#xff1a;") if(88 in test_list):print("存在…

微服务服务拆分和远程调用

一、服务架构比较 单体架构&#xff1a;简单方便&#xff0c;高度耦合&#xff0c;扩展性差&#xff0c;适合小型项目。例如&#xff1a;学生管理系统 分布式架构&#xff1a;松耦合&#xff0c;扩展性好&#xff0c;但架构复杂&#xff0c;难度大。适合大型互联网项目&#x…

【Linux操作系统】深入理解系统调用中的read和write函数

在操作系统中&#xff0c;系统调用是用户程序与操作系统之间进行交互的重要方式。其中&#xff0c;read和write函数是常用的系统调用函数&#xff0c;用于在用户程序和操作系统之间进行数据的读取和写入。本文将深入介绍read和write函数的工作原理、用法以及示例代码&#xff0…

湘大 XTU OJ 1290 Alice and Bob 题解(非常详细):字符串 分类讨论 简单模拟

一、链接 1290 Alice and Bob 二、题目 题目描述 Alice和Bob玩剪刀-石头-布的游戏&#xff0c;请你写个程序判断一下比赛的结果。 输入 第一行是一个整数K&#xff0c;表示样例的个数。 以后每行两个单词&#xff0c;rock表示石头&#xff0c;paper表示布&#xff0c;scis…

Redis 拒绝服务漏洞(CVE-2023-28856)修复处理

一、漏洞描述 Redis Labs Redis是美国Redis Labs公司的一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值&#xff08;Key-Value&#xff09;存储数据库&#xff0c;并提供多种语言的API。 Redis 7.0.0 到 7.0.10版本、6.2.0 到 6.2.11版本、6.0.0 到 …

Git:在本地电脑上如何使用git?

git 版本&#xff1a; 2.40.1.windows.1 文章目录 一. 使用git之前你必须要理解的几个概念1.1 理解工作区、版本库、暂存区的概念1.2 提交Git版本库的步骤【分两步执行】 二. Git本地库实战2.1 初始化版本库2.2 新建 & 提交 & 状态2.3 查看日志2.4 回退 & 穿梭 &am…

树莓派RP2040 用Arduino IDE安装和编译

目录 1 Arduino IDE 1.1 IDE下载 1.2 安装 arduino mbed os rp2040 boards 2 编程-烧录固件 2.1 打开点灯示例程序 2.2 选择Raspberry Pi Pico开发板 2.3 编译程序 2.4 烧录程序 2.4.1 Raspberry Pi Pico开发板首次烧录提示失败 2.4.2 解决首次下载失败问题 2.4.2.1…

FFmpeg 使用总结

FFmpeg 简介 FFmpeg的名称来自MPEG视频编码标准&#xff0c;前面的“FF”代表“Fast Forward”&#xff0c;FFmpeg是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。可以轻易地实现多种视频格式之间的相互转换。包括如下几个部分&#xf…