进程通信与信号

news2024/9/22 4:04:42

1.管道

匿名管道:匿名管道用于进程间通信,且仅限于本地父子进程之间的通信 管道符号 |

进程间通信的本质就是,让不同的进程看到同一份资源,使用匿名管道实现父子进程间通信的原理就是,让两个父子进程先看到同一份被打开的文件资源,然后父子进程就可以对该文件进行写入或是读取操作,进而实现父子进程间通信。这里父子进程看到的同一份文件资源是由操作系统来维护的,所以当父子进程对该文件进行写入操作时,该文件缓冲区当中的数据并不会进行写时拷贝。
管道虽然用的是文件的方案,但操作系统一定不会把进程进行通信的数据刷新到磁盘当中,因为这样做有IO参与会降低效率,而且也没有必要。也就是说,这种文件是一批不会把数据写到磁盘当中的文件,换句话说,磁盘文件和内存文件不一定是一一对应的,有些文件只会在内存当中存在,而不会在磁盘当中存在。
管道的接口 pipe:int pipe(int pipefd[2]); pipe2:   int pipe2(int pipefd[2], int flags);pipe2函数的第二个参数用于设置选项

特性:亲缘性  单向通信  大小  pipe_size(原子性)阻塞属性 非阻塞属性

管道只能够进行单向通信,因此当父进程创建完子进程后,需要确认父子进程谁读谁写,然后关闭相应的读写端。从管道写端写入的数据会被内核缓冲,直到从管道的读端被读取。

命名管道:  创建  mkfifo命令  mkfifo函数    不需要具有亲缘性

int mkfifo(const char *pathname, mode_t mode);mkfifo函数的第一个参数是pathname,表示要创建的命名管道文件。mkfifo函数的第二个参数是mode,表示创建命名管道文件的默认权限。命名管道创建成功,返回0。命名管道创建失败,返回-1。

匿名管道由pipe函数创建并打开。

命名管道由mkfifo函数创建,由open函数打开。

FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在于它们创建与打开的方式不同,一旦这些工作完成之后,它们具有相同的语义。

服务端将信息从输入文件复制到服务端的临时缓冲区中。

将服务端临时缓冲区的信息复制到管道中。

客户端将信息从管道复制到客户端的缓冲区中。

将客户端临时缓冲区的信息复制到输出文件中。

共享内存:    共享内存让不同进程看到同一份资源的方式就是,在物理内存当中申请一块内存空间,然后将这块内存空间分别与各个进程各自的页表之间建立映射,再在虚拟地址空间当中开辟空间并将虚拟地址填充到各自页表的对应位置,使得虚拟地址和物理地址之间建立起对应关系,至此这些进程便看到了同一份物理内存,这块物理内存就叫做共享内存。这里所说的开辟物理空间、建立映射等操作都是调用系统接口完成的,也就是说这些动作都由操作系统来完成。

在物理内存当中申请共享内存空间。

将申请到的共享内存挂接到地址空间,即建立映射关系。

将共享内存与地址空间去关联,即取消映射关系。

释放共享内存空间,即将物理内存归还给系统。

接口:  shmget  shmat  shmdt  shmctl  

创建共享内存  int shmget(key_t key, size_t size, int shmflg);

第一个参数key,表示待创建共享内存在系统当中的唯一标识。第二个参数size,表示待创建共享内存的大小。第三个参数shmflg,表示创建共享内存的方式。shmget调用成功,返回一个有效的共享内存标识符(用户层标识符)。shmget调用失败,返回-1。传入shmget函数的第一个参数key,需要我们使用ftok函数进行获取。ftok函数的作用就是,将一个已存在的路径名pathname和一个整数标识符proj_id转换成一个key值,称为IPC键值,在使用shmget函数获取共享内存时,这个key值会被填充进维护共享内存的数据结构当中。需要注意的是,pathname所指定的文件必须存在且可存取。

控制共享内存  int shmctl(int shmid, int cmd, struct shmid_ds *buf);

第一个参数shmid,表示所控制共享内存的用户级标识符。第二个参数cmd,表示具体的控制动作。第三个参数buf,用于获取或设置所控制共享内存的数据结构。shmctl调用成功,返回0。shmctl调用失败,返回-1。

共享内存连接到进程地址空间  void *shmat(int shmid, const void *shmaddr, int shmflg);

第一个参数shmid,表示待关联共享内存的用户级标识符。第二个参数shmaddr,指定共享内存映射到进程地址空间的某一地址,通常设置为NULL,表示让内核自己决定一个合适的地址位置。第三个参数shmflg,表示关联共享内存时设置的某些属性。shmat调用成功,返回共享内存映射到进程地址空间中的起始地址。shmat调用失败,返回(void*)-1

取消共享内存与进程地址空间之间的关联  int shmdt(const void *shmaddr);

待去关联共享内存的起始地址,即调用shmat函数时得到的起始地址。shmdt调用成功,返回0。shmdt调用失败,返回-1。

特性:  生命周期跟随操作系统  删除特性  覆盖写读访问  

我们若是要将创建的共享内存释放,有两个方法,一就是使用命令释放共享内存,二就是在进程通信完毕后调用释放共享内存的函数进行释放。

从输入文件到共享内存。

从共享内存到输出文件。

3.消息队列

消息队列实际上就是在系统当中创建了一个队列,队列当中的每个成员都是一个数据块,这些数据块都由类型和信息两部分构成,两个互相通信的进程通过某种方式看到同一个消息队列,这两个进程向对方发数据时,都在消息队列的队尾添加数据块,这两个进程获取数据块时,都在消息队列的队头取数据块。消息队列提供了一个从一个进程向另一个进程发送数据块的方法。每个数据块都被认为是有一个类型的,接收者进程接收的数据块可以有不同的类型值。和共享内存一样,消息队列的资源也必须自行删除,否则不会自动清除,因为system V IPC资源的生命周期是随内核的。

接口:  msgget  msgsnd  msgrcv  msgctl

创建消息队列  int msgget(key_t key, int msgflg);

创建消息队列也需要使用ftok函数生成一个key值,这个key值作为msgget函数的第一个参数。

msgget函数的第二个参数,与创建共享内存时使用的shmget函数的第三个参数相同。

消息队列创建成功时,msgget函数返回的一个有效的消息队列标识符(用户层标识符)。

释放消息队列  int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msgctl函数的参数与释放共享内存时使用的shmctl函数的三个参数相同,只不过msgctl函数的第三个参数传入的是消息队列的相关数据结构。

向消息队列发送数据  int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

第一个参数msqid,表示消息队列的用户级标识符。第二个参数msgp,表示待发送的数据块。第三个参数msgsz,表示所发送数据块的大小。第四个参数msgflg,表示发送数据块的方式,一般默认为0即可。msgsnd调用成功,返回0。msgsnd调用失败,返回-1。

从消息队列获取数据  ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

第一个参数msqid,表示消息队列的用户级标识符。第二个参数msgp,表示获取到的数据块,是一个输出型参数。第三个参数msgsz,表示要获取数据块的大小第四个参数msgtyp,表示要接收数据块的类型。msgsnd调用成功,返回实际获取到mtext数组中的字节数。msgsnd调用失败,返回-1。

特性:生命周期跟随操作系统内核

4.进程信号: 信号只能由操作系统发送,但信号发送的方式有多种。

信号产生:软件 硬件 kill命令 

信号的注册:位图  sigqueue队列  非实时信号/实时信号的注册

信号的注销;非实时信号/实时信号的注销

信号的处理方式:默认处理 忽略处理  自定义处理

不能让操作系统直接去执行用户的代码,因为操作系统无法保证用户的代码是合法代码,即操作系统不信任任何用户。

 

信号的自定义处理:signal  sigaction

sigaction函数可以读取和修改与指定信号相关联的处理动作

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

signum代表指定信号的编号。若act指针非空,则根据act修改该信号的处理动作。若oldact指针非空,则通过oldact传出该信号原来的处理动作。

 信号的捕捉流程:do_signal

信号的阻塞:阻塞位图  sigset_t block  信号的阻塞不会影响信号的注册

gcc的优化选项 volatile  

自定义处理SIGCHLD

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【云原生】Docker跨主机网络Overlay与Macvlan的区别

跨主机网络通信解决方案 docker原生的overlay和macvlan 第三方的flannel,weave,calico 1.overlay网络 在Docker中,Overlay网络是一种容器网络驱动程序,它允许在多个Docker主机上创建一个虚拟网络,使得容器可以通过这…

Python 最优传输工具箱(Python Optimal Transport)

最近在研究最优传输的相关理论,博主使用的是python编程语言,在这里给大家推荐一个Python最优传输工具箱:Python Optimal Transport(pot)与geomloss 其中geomloss是针对pytorch张量的,ot是针对numpy数组的;g…

装饰器模式揭秘:我用装饰器给手机集成了ChatGPT

在平时的开发过程中,我们经常会遇到需要给一个类增加额外功能的需求,但又不想破坏类的原有结构。这时候,装饰器模式就能大显神威了!接下来,我将带你深入了解装饰器模式的原理、优缺点、适用场景以及如何在实际开发中巧…

无法找到docker.sock

os环境:麒麟v10(申威) 问题描述: systemctl start docker 然后无法使用docker [rootnode2 ~]# systemctl restart docker [rootnode2 ~]# docker ps Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon r…

4、应用层https27

https协议加密流程:使用ssl加密。 一、HTTPS协议 对HTTP协议进行加密后的一个新的协议。 1、加密概念 单说数据加密过去狭义,更多的是防止数据被监听劫持。 加密包含俩个方面:身份验证,加密传输。 1.1身份验证 验证对端的身…

四、传播

文章目录 1、草药迷阵问题2、时序回溯搜索3、传播搜索THE END 1、草药迷阵问题 \qquad 有一个10*10的百草药柜,每一个抽屉里都有5种不同属性的草药,依次打开抽屉来长出草药迷阵,要求寻找一种神奇的药方,满足: 横行&am…

数据结构——C++无锁队列

数据结构——C无锁队列 贺志国 2023.7.11 上一篇博客给出了最简单的C数据结构——堆栈的几种无锁实现方法。队列的挑战与栈的有些不同,因为Push()和Pop()函数在队列中操作的不是同一个地方。因此同步的需求就不一样。需要保证对一端的修改是正确的,且对…

(中等)LeetCode 3. 无重复字符到的最长子串 Java

滑动窗口 以示例一为例,找出从每一个字符开始的,不包含重复字符的最长子串,那么,其中最长的那个字符串即为答案。 当我们一次递增地枚举子串的起始位置,会发现子串的结束位置也是递增的,原因在于&#xf…

Django项目创建

Django项目创建 文章目录 Django项目创建👨‍🏫方式一:终端命令行方式👨‍🔬方式二:Pycharm创建 👨‍🏫方式一:终端命令行方式 1️⃣cmd打开终端,切换到指定目…

WebSell管理工具--中国蚁剑安装教程以及初始化

简介:中国蚁剑是一款开源的跨平台WebShell网站管理工具 蚁剑的下载安装: GitHub项目地址:https://github.com/AntSwordProject/ Windows下载安装: 百度网盘下载链接:链接:https://pan.baidu.com/s/1A5wK…

超细整理,性能测试-性能指标监控命令详细实战,一篇速通

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 性能监控命令&…

自动驾驶代客泊车AVP摄像头与ECU交互需求规范

目录 1 文档范围及控制方法... 5 1.1 目的.... 5 1.2 文档授权... 5 1.3 文档变更管理... 5 1.4 缩写.... 5 1.5 术语.... 5 2 系统组成... 6 2.1 系统框图... 6 2.2 电源供应和时序要求... 7 2.2.1 摄像头供电控制... 7 2.2.2 摄像头上电时序要求…

论文(3)——使用ChatGPT快速提高科研能力!!如何快速构建代码?怎么提高自己的科研能力?如何提高自己的生产力?

文章目录 引言问题描述问题解决智能开发软件的方法ChatGPT Plus 代码解释器使用ChatGPT插件功能 代码工具Coplit学生优惠免费申请Coplit和pycharm的结合 NewBing的申请 总结参考引用 引言 chatGPT大模型用于问问题和debug,NewBing用于搜索论文,cpolit用…

简述HashMap的扩容机制

注意:本博客需要对HashMap源码有过一定理解,看过源码比较好,仅供互相学习参考 JDK1.7和JDK1.8对比 1.7版本: (1). 首先生成一个新数组(2). 遍历老数组每个位置中的链表元素(3). 取每个元素的key,重新计算每个元素在…

深度学习ai学习方向如何规划,算法竞赛,机器学习,搭建环境等答疑

目录 1了解人工智能的背景知识 2 补充数学或编程知识 3 熟悉机器学习工具库 4 系统的学习人工智能 5 动手去做一些AI应用 1了解人工智能的背景知识 一些虽然存在但是在研究或者工业上不常用的知识,为自己腾出更多的时间来去学习,研究。 人工智能里…

2023.7.16-约数的枚举

功能&#xff1a;输入一个整数&#xff0c;结果打印出这个整数所有的约数。 程序&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() {int a0, b;printf("请输入一个整数&#xff1a;");scanf("%d",&a);printf(&qu…

迭代器模式:相比直接遍历集合数据,使用迭代器有哪些优势?

今天&#xff0c;我们学习另外一种行为型设计模式&#xff0c;迭代器模式。它用来遍历集合对象。不过&#xff0c;很多编程语言都将迭代器作为一个基础的类库&#xff0c;直接提供出来了。在平时开发中&#xff0c;特别是业务开发&#xff0c;我们直接使用即可&#xff0c;很少…

前端基础:HTML和CSS简介

目录 1、HTML 简介 &#xff08;1&#xff09;在 HTML 中引入外部 CSS &#xff08;2&#xff09;在 HTML 中引入外部 JavaScript 2、CSS 简介 &#xff08;1&#xff09;CSS 的基本语法 &#xff08;2&#xff09;三种使用 CSS 的方法 2.1 - 外部 CSS 的使用 2.2 - 内…

Redis简介与安装

文章目录 前言一、Redis简介1. Redis是什么2. Redis的特点3. 数据库类型4. Redis 应用场景 二、Redis下载与安装1. Redis安装包下载地址2. 在 windows系统安装 Redis3. 在Linux系统安装Redis 总结 前言 为了巩固所学的知识&#xff0c;作者尝试着开始发布一些学习笔记类的博客…

面向对象习题

创建类Calc,定义2个数属性以及一个符号属性,编写4个方法add、minus、multiply、divide,4个方法分别进行2个小数的加、减、乘、除运算.在主函数里面接受用户输入2个运算数、1个运算符,根据该运算符选择应该调用哪一个方法进行运算。 定义10名学生&#xff0c;循环接收10名学员的…