day7:消息队列与共享内存

思维导图:

消息队列原理:

进程在内核空间中维护出消息队列,每个进程借由消息队列的msgid对消息队列进行读写操作,消息队列中的信息是一个结构体,存储着消息的种类(身份证)和消息的内容,多个进程间可以通过消息的种类来进行通讯,例如:进程A放了一个种类为A的信息,进程B只读取种类为A的信息,通过这种方式实现了进程间的定向信息传输。

共享内存原理:

共享内存第一步是先将一块物理内存映射到内核空间,在内核空间维护出一块共享内存,然后每个进程可以通过指针的方式共同访问这块内存空间,并进行读写操作,实现进程通信。类似malloc用法。

使用消息列队实现两个进程间接受发送信息

发送端:

#include <head.h>
typedef struct m
{long type;char text[1024];
}sake;
#define SIZE sizeof(struct m)-sizeof(long)
int main(int argc, const char *argv[])
{	key_t key;if((key=ftok("/",'a'))==-1){perror("");return -1;}int msgid=0;if((msgid=msgget(key,IPC_CREAT|0664))==-1){perror("");return -1;}pid_t pid;pid=fork();if(pid>0){sake message;while(1){	message.type=1;printf("传送的信息:");scanf("%s",message.text);printf("%s\n",message.text);msgsnd(msgid,&message,SIZE,0);if(strcmp(message.text,"quit")==0){break;}}}else if(pid==0){sake message;while(1){	msgrcv(msgid,&message,SIZE,2,0);if(strcmp(message.text,"quit")==0){break;}printf("接收到的消息为:%s\n",message.text);}}return 0;
}

接收端:

#include <head.h>
typedef struct m
{long type;char text[1024];
}sake;
#define SIZE sizeof(sake)-sizeof(long)
int main(int argc, const char *argv[])
{key_t key;if((key=ftok("/",'a'))==-1){perror("");return -1;}int msgid;if((msgid=msgget(key,IPC_CREAT|0664))==-1){perror("");return -1;}pid_t pid;pid=fork();if(pid>0){sake message;while(1){	message.type=2;printf("传送的信息:");scanf("%s",message.text);msgsnd(msgid,&message,SIZE,0);if(strcmp(message.text,"quit")==0){break;}}}else if(pid==0){sake message;while(1){	msgrcv(msgid,&message,SIZE,1,0);if(strcmp(message.text,"quit")==0){break;}printf("接收到的消息为:%s\n",message.text);}}if(msgctl(msgid,IPC_RMID,NULL)==-1){perror("");return -1;}return 0;
}

复现消息列队代码:

发送端:

#include <head.h>
typedef struct message
{long mtype;char mtext[1024];
}sake;
#define SIZE sizeof(sake)-sizeof(long)
int main(int argc, const char *argv[])
{key_t key;if((key=ftok("/",'a'))==-1){perror("");return -1;}int msgq=0;if((msgq=msgget(key,IPC_CREAT|0664))==-1){perror("");return -1;}sake msg;while(1){long mt=0;printf("请输入消息类型:");scanf("%ld",&mt);msg.mtype=mt;char buf[1024];printf("请输入发送的消息:");scanf("%s",buf);strcpy(msg.mtext,buf);msgsnd(msgq,&msg,SIZE,0);printf("operation success\n");}if(msgctl(msgq,IPC_RMID,NULL)==-1){printf("error\n");return -1;}return 0;
}

接收端:

#include <head.h>
typedef struct message
{long mtype;char mtext[1024];
}sake;
#define SIZE sizeof(sake)-sizeof(long)
int main(int argc, const char *argv[])
{key_t key;if((key=ftok("/",'a'))==-1){perror("");return -1;}int msgq=0;if((msgq=msgget(key,IPC_CREAT|0664))==-1){perror("");return -1;}sake msg;while(1){msgrcv(msgq,&msg,SIZE,1,0);printf("收到的数据为:%s\n",msg.mtext);}return 0;
}

复现共享内存代码

发送端:

#include <head.h>
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{key_t key;if((key=ftok("/",'a'))==-1){perror("");return -1;}int shmid;if((shmid=shmget(key,4096,IPC_CREAT|0664))==-1){perror("");return -1;}char *ptr=NULL;ptr=(char *)shmat(shmid,NULL,0);while(1){fgets(ptr,PAGE_SIZE,stdin);ptr[strlen(ptr)-1]='\0';if(strcmp(ptr,"quit")==0){break;}}if(shmdt(ptr)==-1){perror("");return -1;}if(shmctl(shmid,IPC_RMID,NULL)==-1){perror("");return -1;}return 0;
}

接收端:

#include <head.h>
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{key_t key;if((key=ftok("/",'a'))==-1){perror("");return -1;}int shmid;if((shmid=shmget(key,4096,IPC_CREAT|0664))==-1){perror("");return -1;}char *ptr=NULL;ptr=(char *)shmat(shmid,NULL,0);while(1){printf("收到的数据为%s\n",ptr);sleep(3);if(strcmp(ptr,"quit")==0){break;}}if(shmdt(ptr)==-1){perror("");return -1;}return 0;
}

面试题整理:

进程和线程的区别是什么:

相同点:他们都遵循时间片轮询,上下文切换原则,

不同点:进程是资源分配的最小单位,线程是任务执行的最小单位

                在一个进程中的线程共享进程的资源,而进程之间相互独立

                线程是进程的执行单元,一个进程可以包含多个线程

如何在Linux系统中实现同步

实现同步的方式主要有两种,一种是无名信号量。无名信号量本质上是个临界资源,所有线程在执行前会去访问自己对应的无名信号量,在别的线程将自己的无名信号量增加后方可执行。

第二种是同步互斥机制中的条件变量,它结合了互斥锁思想,所有线程先获取锁资源,然后进入到消息队列后将锁资源打开供其他线程进入队列,等到条件变量被唤醒,再同时让所有再队列中的线程去获取锁资源

互斥的概念及实现

互斥指同一时刻只有一个线程可以执行,没有先后顺序,谁抢到资源谁先执行

主要依靠互斥锁进行工作,互斥锁本质上是个临界资源,所有线程再执行前先访问锁资源,访问到了便将其上锁,其他线程无法访问到锁资源。等到线程结束再释放锁资源供下次争抢。

fork()调用后,父进程和子进程的执行顺序是什么样的,他们如何共享资源

没有执行顺序,遵循时间片轮询上下文切换原则

子进程会拷贝父进程的资源,在fork语句之前的资源子进程都能使用,且相互独立

什么是僵尸进程?如何避免?

僵尸进程是指子进程已经结束但是父进程未回收其资源

可以利用signal函数,当子进程结束后,子进程会对父进程发送SIG_CHLD信号,父进程可以利用signal函数捕获这种信号,然后利用回调函数回收子进程资源。

Linux中进程间的通信方式

无名管道,有名管道,信号

消息队列,共享内存,信号量(信号灯集)

套接字

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《数据结构、算法与应用C++语言描述》-红黑树的C++实现-百万级数据量测试通过

红黑树 完整可编译运行代码见仓库&#xff1a;GitHub - Jasmine-up/Data-Structures-Algorithms-and-Applications/_3matrix。 如有问题请在评论区指出。另外&#xff0c;Github仓库会根据我的学习情况持续更新&#xff0c;欢迎大家点star&#xff0c;谢谢。 基本概念 红-黑…

智数融合|低代码入局,推动工业数字化转型走"深"向"实"

当下&#xff0c;“数字化、智能化”已经不再是新鲜词汇。事实上&#xff0c;早在几年前&#xff0c;就有企业开始大力推动数字化转型&#xff0c;并持续进行了一段时间。一些业内人士甚至认为&#xff0c;“如今的企业数字化已经走过了成熟期&#xff0c;进入了深水区。” 但事…

虚幻UE 材质-进阶边界混合之距离场限制PDO范围

基础边界混合那篇文章&#xff1a;虚幻UE 材质-边界混合之PDO像素深度偏移量 可以通过抖动来进行混合&#xff0c;但是有问题的点在与抖动发生的位置只需要在两物体的交界处 所以本篇文章会通过距离场限制来限制抖动的位置&#xff0c;防止其他地方发生抖动影响画面。 文章目录…

三、yolov8训练结果查看和模型预测

训练结果查看 1、在模型训练结束后&#xff0c;如下图所示&#xff0c;找到该文件夹。 2、然后找到weights文件夹中的best.pt文件&#xff0c;这就是该数据训练后的模型。 模型预测 1、在assets文件夹下创建FPC-2文件夹&#xff0c;放入一些同类FPC预测结果。 2、和训练…

HarmonyOS@Link装饰器:父子双向同步

Link装饰器&#xff1a;父子双向同步 子组件中被Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。 说明 从API version 9开始&#xff0c;该装饰器支持在ArkTS卡片中使用。 概述 Link装饰的变量与其父组件中的数据源共享相同的值。 装饰器使用规则说明 Link变…

SpringMVC-异常处理及常用组件

异常处理器 1.基于配置的异常处理 springmvc提供了一个处理控制器方法执行过程中所出现的异常的接口: HandlerExceptionResolver HandlerExceptionResolver接口的实现类有: DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver springmvc提供了自定义的异常处…

【python】爬取豆瓣电影排行榜Top250存储到Excel文件中【附源码】

英杰社区https://bbs.csdn.net/topics/617804998 一、背景 近年来&#xff0c;Python在数据爬取和处理方面的应用越来越广泛。本文将介绍一个基于Python的爬虫程 序&#xff0c;用于抓取豆瓣电影Top250的相关信息&#xff0c;并将其保存为Excel文件。 程序包含以下几个部…

数据库的导入导出以及备份

1.数据库的导出和导入 一.navicat导入导出 导入&#xff1a;右键➡运行SQL文件 导出选&#xff1a;中要导出的表➡右键➡转储SQL文件➡数据和结构 mysqldump命 1. 进入navicat安装目录的bin目录&#xff0c;cmd打开命令窗口 2. mysql -u用户名 -p ➡ 输入密码 3. creat…

李沐之神经网络基础

目录 1.模型构造 1.1层和块 1.2自定义块 1.3顺序块 1.4在前向传播函数中执行代码 2.参数管理 2.1参数访问 2.2参数初始化 3.自定义层 3.1不带参数的层 3.2带参数的层 4.读写文件 4.1加载和保存张量 4.2加载和保存模型参数 1.模型构造 1.1层和块 import torch fr…

K2P路由器刷OpenWrt官方最新版本固件OpenWrt 23.05.2方法 其他型号的智能路由器OpenWrt固件刷入方法也基本上适用

最近路由器在开机时总出问题,于是就那他来开刀,直接刷一个OpenWrt官方最新版本的固件, 刷其他第三方的固件总是觉得不安全, 而且很多第三方固件都带了些小工具,始终会有安全隐患, 而且占用内存空间太多,本来这个东西就没有多少内存,于是就干脆刷一个官方的原始固件(才6.3M, 相…

网卡高级设置-提高网络环境

网卡高级设置&#xff0c;提高网络质量排除一些连接问题 一、有线网卡 1、关闭IPv6&#xff1b; 可以关闭协议版本6&#xff0c;因为它会引起一些网络连接问题&#xff0c;而且现在几乎用不到IP6。 2、关闭节约电源模式&#xff1b; 右击计算机->设备->设备管理器-&…

视频智能分析/边缘计算AI智能分析网关V4区域入侵检测算法如何配置?

边缘计算AI智能分析网关&#xff08;V4版&#xff09;部署了近40种AI算法模型&#xff0c;支持对接入的视频图像进行人、车、物、行为等实时检测分析&#xff0c;并上报识别结果&#xff0c;并能进行语音告警播放。算法配置后&#xff0c;即可对监控视频流进行实时检测&#xf…