Linux进程间通信IPC

本文涉及的产品
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 1个月
简介: Linux进程间通信IPC

简介


进程之间具有独立性,无法直接通信,因为每个进程都有一个自己独立的虚拟地址空间。


因此让进程间能够通信,本质上就是给进程间提供一块公共的区域,让需要通信的进程都能够访问这块区域,从而就能实现通信。


根据通信应用场景不同,提供的方式也有多种,如:数据传输、数据共享、协调控制


进程间常见的4种通信方式:


       数据传输:管道、消息队列


       数据共享:共享内存


       进程控制:信号量


· 四种进程间通信方式★


一、管道


1.相关特性


使用场景:数据传输


★特性:半双工通信(可以选择方向的单向通信)


       若管道中没有数据,read默认会阻塞等待,直到读取到数据后返回;


       若管道中数据写满,write默认会阻塞,直到数据被读出有空闲空间。


       管道的读写是一种字节流传输服务,数据会在缓冲区堆积,并且遵循先进先出规则。


       若管道所有写端被关闭,read读取完缓冲区数据后,继续读取read将不再阻塞,而是返回0


(所有管道read返回0,表示的是继续读取没有意义)。


       若管道所有读端被关闭,write继续写入数据,则会触发异常,退出程序。


★本质:内核中的一块缓冲区(内核空间的一块内存)


分类:


       匿名管道:内核中的缓冲区没有标识符


       命名管道:内核中的缓冲区具有标识符


2.匿名管道


       因为没有标识符,所以只能用于具有亲缘关系的进程间通信。


       只有通过子进程复制父进程的方式获取操作句柄。


(父进程创建管道后,在创建子进程时,子进程会复制父进程pcb中的大部分信息,其中也包括父进程的管道操作句柄,这样父子进程中的管道操作句柄访问的就是同一个内核缓冲区,从而实现进程间通信)


image.png


3.命名管道


       命名管道的标识符是一个可见于文件系统的特殊管道文件,多个进程通过打开同一个管道文件,访问内核中的同一块缓冲区。


image.png


注意:管道文件只是为了让多个进程找到内核中的同一块缓冲区。


4.管道操作★


4.1匿名管道


int pipe(int pipefd[2]);


功能:创建一个匿名管道


       pipefd[0]:用于从管道中读取数据;


       pipefd[1]:用于向管道中写入数据。


返回值:


       成功:返回0;


       失败:返回-1。


4.2命名管道


int mkfifo(const char* pathname, mode_t mode);


功能:创建一个命名管道的标识符(命名管道文件)


       pathname:带有路径文件名称


       mode:文件权限


返回值:


       成功,返回0;


       失败,返回-1;


       EEXIST,文件已存在。


注意:mkfifo只是创建了一个管道的标识符,后续对于命名管道的操作类似于对普通文件操作。


打开特性:


       如果管道文件被只读打开,就会阻塞,直到管道文件被以写方式也打开;


       如果管道文件被只写打开,也会阻塞,直到管道文件被以读方式也打开。


5.管道总结★


       管道的本质就是内核中的一块缓冲区,分为匿名管道和命名管道。其中匿名管道只能用于具有亲缘关系的进程间通信。


特性:


1)半双工通信;


2) 提供字节流传输服务:


       先进先出;


        基于连接:所有读端关闭write异常,所有写端关闭read返回0不阻塞


3)生命周期跟随进程


4)自带同步与互斥:


       互斥:资源在同一时间只有一个进程可以访问


                管道的写入操作大小不超过PIPE_BUF(默认4096字节)大小时保证原子操作


               (原子操作:要么一次性完成,无法被打断;要么不做。)


       同步:通过某些条件限制,让进程对资源访问更加合理


               若管道中没有数据,则read阻塞;


               若管道中数据已满,则write阻塞。


二、共享内存


1.相关特性


使用场景:实现进程间的数据共享


★特性:最快的进程间通信方式


原理:


       申请一块物理内存,需要进行数据共享的进程将同一块物理内存映射到自己的虚拟地址空间,然后通过虚拟地址直接访问。相较于其他通信方式,没有了两次用户空间与内核空间之间的数据拷贝操作,因此速度最快。


2.操作流程


       1)创建/打开共享内存


       2)将共享内存映射到虚拟地址空间


       3)共享内存操作


       4)解除映射关系


       5)删除共享内存


3.操作接口


3.1创建或打开操作


int shmget (key_t key, size_t size, int shmflag);
        key:标识符,多个进程通过标识符打开同一个共享内存;
        size:共享内存大小;
        shmflag:打开方式&权限;
                打开方式:IPC_CREAT,......;
                权限:0777,......;


返回值:


       成功,返回操作句柄(非负整数);


       失败,返回-1。


3.2建立映射关系操作


void *shmat(int shmid, void *addr, int shmflag);
        shmid:shmget返回的操作句柄;
        addr:指定映射首地址(通常置NULL);
        shmflag:要进行的操作
                SHM_RDONLY:只读;
                默认给0:可读可写;


返回值:


       成功,返回映射的首地址;


       失败,返回(void*)-1。


3.3解除映射关系操作


int shmdt(void *shm_start);
        shm_start:shmat映射的首地址。


3.4删除共享内存操作


int shmct(int shmid, int cmd,  struct shmid_ds *buf);
        shmid:shmget返回的句柄;
        cmd:要对共享内存的操作
                删除:IPC_RMID
                ......;
        buf:用于设置或获取共享内存信息,不使用则设置为NULL。


返回值:对于删除操作


       成功:返回0;


       失败:返回-1。


★注意:


共享内存的删除,实际上并不会立即删除共享内存,而是将共享内存标记为被删除状态,拒绝后续的新建映射,等到映射连接数为0时,自动释放共享内存段。


4.共享内存总结


4.1本质原理


       共享内存的本质就是开辟了一块物理内存,将其映射到多个进程的虚拟地址空间中,进程通过映射后的虚拟地址直接访问同一块物理内存,实现数据共享。


4.2特性


       最快的进程间通信方式(相较于其他方式,少了用户空间与内核空间之间的两步数据拷贝操作)。


       生命周期随内核。


4.3注意事项


多个进程对共享内存进行操作,存在操作安全隐患。


三、消息队列


使用场景:用于实现进程间的数据传输


本质:内核中的一个优先级队列


原理:多个进程通过访问同一个内核中的消息队列,向队列中添加节点、获取节点,实现数据传输


特性:


       消息队列自带同步与互斥;


       生命周期随内核。


四、信号量


使用场景:用于实现进程间的同步与互斥


本质:内核中的一个计数器和pcb等待队列


原理:针对资源进行计数,实现同步与互斥


操作:PV操作


       P操作:在获取或者访问资源前进行P操作


               对计数器进行判断,若小于等于0,则阻塞进程并且计数器-1;


               若计数器大于0,则计数器-1,操作正确返回。


       V操作:在产生资源之后进行V操作


               计数器加1,并唤醒一个等待中的进程。


同步实现:


       对资源进行计数,在资源获取之前进行P操作,在产生资源后进行V操作。


互斥实现:


       将资源计数器初始化为1,表示资源只有一个。


       在访问数据前进行P操作,访问数据完毕之后进行V操作,从而实现同一个资源同一时间内,只有一个进程能够进行访问。


五、进程间通信资源的命令操作


1. ipcs 查看进程间通信资源


语法:ipcs [选项]


-m:共享内存


-s:信号量


-q:消息队列


2. ipcrm 删除进程间通信资源


语法:ipcrm [选项] 资源id


1.png

 


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
相关文章
|
17天前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
51 4
linux进程管理万字详解!!!
|
8天前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
48 8
|
17天前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
52 4
|
18天前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
19天前
|
消息中间件 存储 Linux
|
26天前
|
运维 Linux
Linux查找占用的端口,并杀死进程的简单方法
通过上述步骤和命令,您能够迅速识别并根据实际情况管理Linux系统中占用特定端口的进程。为了获得更全面的服务器管理技巧和解决方案,提供了丰富的资源和专业服务,是您提升运维技能的理想选择。
31 1
|
1月前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
【10月更文挑战第9天】本文将深入浅出地介绍Linux系统中的进程管理机制,包括进程的概念、状态、调度以及如何在Linux环境下进行进程控制。我们将通过直观的语言和生动的比喻,让读者轻松掌握这一核心概念。文章不仅适合初学者构建基础,也能帮助有经验的用户加深对进程管理的理解。
25 1
|
1月前
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
31 0
Linux c/c++之IPC进程间通信
|
6月前
|
存储 缓存 Linux
【Linux】进程概念(冯诺依曼体系结构、操作系统、进程)-- 详解
【Linux】进程概念(冯诺依曼体系结构、操作系统、进程)-- 详解
|
3月前
|
Linux Shell 调度
【在Linux世界中追寻伟大的One Piece】Linux进程概念
【在Linux世界中追寻伟大的One Piece】Linux进程概念
40 1
下一篇
无影云桌面