当前位置: 首页 > news >正文

Linux操作系统编程——进程间的通信

        由于进程间空间独立,无法直接通信,所以需要IPC机制实现通信

        同一主机进程间通信

                1,古老的通信方式:无名管道;有名管道;信号

                2,IPC对象通信system v:共享内存(效率最高);消息队列;信号量集(信号灯)

        不同主机之间的通信:socket通信;网络通信

        通信类型

                单工:数据传输是完全单向的,通信双方严格分工,一方固定为发送端(只能发不能收),另一方固定为接收端(只能收不能发),传输方向不可改变,例如广播

                半双工:数据传输允许双向进行,但同一时刻只能单向传输 ,发送和接收功能不能同时开展,需交替进行,例如对讲机    

                全双工:数据传输可同时双向进行,发送端和接收端能独立收发数据,无需等待切换例如打电话

古老方式

管道

        有名管道:可以用于同一主机任意进程间通信

        无名管道:只能用于同一主机具有亲缘关系的进程通信(父子进程之间)

无名管道

        本质:内核空间中的一段缓冲区,遵循先进先出特性

        默认大小:64K

        特性:

                1,写堵塞:读端和写端都存在时,向管道中写数据,当管道满时,发生写阻塞

                2,读阻塞:读端和写端都存在时,向管道中读数据,若管道为空,发生读阻塞

                3,读返回0:当写端关闭,从管道中读数据,若有数据则读到数据,若没有数据则read返回0,不再阻塞

                4,管道破裂:读端关闭,向管道中写入数据。这是一种异常,操作系统会强制让进程结束

        操作流程:

                1)创建无名管道:pipe()

                2)写管道:write()

                3)读管道:read()

                4)关闭管道:close()

        不必刻意释放,因为属于内核区域,关闭会自动释放

pipe

        参数:

                pipefd[0]为读端

                pipefd[1]为写端

        返回值:成功则0失败-1

        管道文件应该在fork()之前创建。读写端不能交换

memset()

        功能:将内存区域填充成指定数据

        参数:

                s:要填充的空间首地址

                c:要填充的字符

                n:要填充的字节数

        返回值:成功则为s的首地址,失败则为NULL

        一般情况下,不会让一个进程既可写又可读,保证管道的方向性,如果要两个进程互相通信,需要构建两个管道

有名管道

        本质:内核空间的一段缓冲区,这段缓冲区和一个管道文件相关联

        操作流程:

                1,创建管道文件:mkififo()

                2,打开管道文件:open()

                3,读或写管道文件:write()

                4,关闭管道文件:close()

                5,删除管道文件:remove()

mkfifo()

        功能:创建管道文件

        参数:管道文件的名称;管道文件的读写执行权限

        返回值:成功为0失败-1

        open会有阻塞的效果,当以只读的方式打开时,会阻塞直到有进程以写的方式打开,对于只写方式同理

        效果是向一个进程输入字符串,另一个进程打印出来

信号

        实现进程间通知机制,实现进程间的异步通信(接收方不知道什么时候发送方会发送时数据),是一种软中断

分类

        系统支持的信号:

                1,kill -l

                        2)SIGINT(crtl + c)让一个进程被打断

                        3)SIGQUIT(ctrl + \)让一个进程结束

                        9)SIGKILL(管理员信号):强制让一个进程结束

                       11)SIGSEGV:让一个进程结束(段错误)

                       13)SIGIPIPE:让一个进程结束(管道破裂)

                       14)SIGALRM:让一个进程结束(定时时间到达)

                       17)SIGCHLD:子进程结束时发送给父进程

                       18)SIGCONT:让停止态的进程继续运行

                       19)SIGSTOP(管理员信号):让运行态的进程进入停止态(暂停)强制停止

                       20)SIGTSTP(ctrl + z):让后台进程进入暂停态,时来自终端的停止信号

                2,信号处理流程

                3,信号处理方式

                        1)缺省:按照默认处理方式

                        2)忽略:不处理

                        3)捕获:以自定义方式处理

                        值得注意的是,管理员信号无法被忽略和捕获,即9和19只能按照默认方式处理

signal

        功能:设置信号的处理方式(注册一个信号)

        参数:

                signum:要处理的信号的编号

                handle:

                        SIG_IGN:以忽略的方式处理该信号,即不处理

                        SIG_DFL:以缺省的方式处理,即系统默认方式

                        函数的地址:以捕获方式处理,即自定义

        返回值:失败则为NULL;自定义方式时,返回函数的地址

        注意:

                1,若信号不被注册,则按默认方式处理

                2,信号只需注册一次

                3,每次信号的到来,都会触发一次信号处理函数

                4,信号尽可能早注册

        如图,signal按照handler的方式运行,所以此时SIGINT信号并不能打断该进程,即按照系统默认的方式运行

发送信号

        1,kill命令

        2,kill()

                功能:给指定的进程发送一个信号

                参数:接收信号的进程的pid;信号的编号

                返回值:成功则0失败-1

        3,子进程结束时,会发送SIGCHLD(17)信号给父进程

              子进程空间异步回收:通过子进程发送的SIGCGLD信号实现

        4,raise():给自己所在的进程发送信号

        5,alarm()

                功能:设置一个闹钟,闹钟时间到达时,向进程发送一个SIGALRM的信号

                参数:秒数

                返回值:成功则为上次设定剩余的时间,失败则为0

                注:如果定了两个,则第一个会失去效果

        6,pause():让一个进程进入到睡眠状态

                注:pause可以被一个可以被捕获的信号唤醒

IPC

        可以通过ipcs -a查看内核终端IPC对象,-s为删除信号量集,-m+id为删除共享内存

共享内存

        使用内核空间中的内存区域共享数据,采用内存映射技术,减少的数据的反复拷贝,提高了通信效率,本质是通过MMU(内存管理单元)的管理将不同的内存空间映射到同一物理内存区域中

        操作流程:

                1)创建一个IPC key:key_t ftok(const char *pathname, int proj_id)

                2)创建共享内存:shmget

                3)建立共享内存段和用户空间的内存映射:shmat

                4)向共享内存写入数据:通过用户空间首地址

                5)解除映射关系:shmdt

                6)删除共享内存:shmctl

ftok

        功能:创建一个IPC key

        参数:

                pathname:路径,随便写,只需在两个进程之间创建key时传递的路径相同

                proj_id:工程ID,与其他key不冲突,一般来说会用特殊的字符表示,例如'!'

        返回值:成功则为IPC key,失败则为-1

        注意:两个进程在创建KEY时,必须使用相同的参数,

shmget

        功能:创建一个共享内存

        参数:

                key:IPC key

                size:共享内存大小,会被扩展成PAGE_SIZE(4096byte)的整数倍

                shmflg:IPC_CREAT|0664(创建并给予权限)

        大小不超过1G,因为内核大小只有1G,而且一般情况下共享内存最大500M

        返回值:成功则为共享内存的ID,失败则为-1

shmat

        功能:建立共享内存映射

        参数:

                shmid:共享内存的id

                shmaddr:映射的用户空间首地址,如果是NULL则是让操作系统分配

                shmflg:

                        SHM_RDONLY:只读

                        !SHM_RDONLY:可读可写

        返回值:成功则为映射的用户空间首地址,失败则为(void *)-1

shmdt

        功能:解除内存映射关系

        参数:要解除的用户空间首地址

        返回值:成功为0失败-1

shmctl

        功能:操作共享内存

        参数:

                shmid:要操作的共享内存id

                cmd:要执行的操作指令

                        IPC_RMID:删除操作

                buf:设置的参数(删除的时候不需要)

                返回值:成功为0失败-1

信号量集

        实现进程间同步

消息队列

        和管道类似,有同步的效果,相对于管道而已增加了数据的等级,可以优先处理优先级较高的数据

http://www.xdnf.cn/news/1328797.html

相关文章:

  • RocketMq消费者动态订阅topic
  • RK3568 Linux驱动学习——Linux设备树
  • Linux下Mysql命令,创建mysql,删除mysql
  • Win/Linux笔记本合盖不睡眠设置指南
  • 小程序插件使用
  • RWA加密金融高峰论坛星链品牌全球发布 —— 稳定币与Web3的香港新篇章
  • Vue 2 项目中快速集成 Jest 单元测试(超详细教程)
  • 哈希:两数之和
  • 从零开始的云计算生活——第四十六天,铁杵成针,kubernetes模块之Configmap资源与Secret资源对象
  • 【技术揭秘】AI Agent操作系统架构演进:从单体到分布式智能的跃迁
  • 告别手写文档!Spring Boot API 文档终极解决方案:SpringDoc OpenAPI
  • 大数据数据库 —— 初见loTDB
  • 视觉采集模块的用法
  • A股大盘数据-20250819 分析
  • 云原生俱乐部-shell知识点归纳(1)
  • 力扣57:插入区间
  • 决策树剪枝及数据处理
  • AI 药物发现:化学分子到机器学习数值特征的转化——打通“化学空间”与“模型空间”关键路径
  • 【Git 子模块与动态路由映射技术分析文档】
  • Matplotlib数据可视化实战:Matplotlib子图布局与管理入门
  • 疏老师-python训练营-Day50预训练模型+CBAM注意力
  • PCL+Spigot服务器+python进行MC编程(使用Trae进行AI编程)---可以生成彩虹
  • Hugging Face 核心组件介绍
  • 35岁对工作的一些感悟
  • Ansible 中的文件包含与导入机制
  • noetic版本/ubuntu20 通过moveit控制真实机械臂
  • 常见的对比学习的损失函数
  • DataAnalytics之Tool:Metabase的简介、安装和使用方法、案例应用之详细攻略
  • 数字ic后端设计从入门到精通14(含fusion compiler, tcl教学)半定制后端设计
  • plantsimulation知识点25.8.19 工件不在RGV中心怎么办?