Linux——进程间通信(共享内存)

目录

system V共享内存

​编辑

共享内存函数

共享内存的建立过程

shmget函数

shmctl函数

shmat函数

shmdt函数

实例代码

共享内存的特点


system V共享内存

共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间(即内存通过某种映射关系连接到了进程使得进程能够访问这段内存),这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。

共享内存函数

我们之前的文章介绍的管道通信本质是基于文件的,OS没有做过多的设计工作。

而system V进程间通信是OS特地设计的通信方式,是为了想尽一切办法让不同的进程看到同一份资源。(具体的方法就是将物理内存映射到进程的地址空间中,本质就是修改页表,在虚拟地址空间中开辟空间,用的是系统调用接口)

共享内存的建立过程

1、申请共享内存

2、共享内存挂接到地址空间

3、去关联共享内存

4、释放共享内存

前两点式通信过程,后两点是释放资源的过程

shmget函数

功能:用来创建共享内存

原型

        int shmget(key_t key, size_t size, int shmflg);

参数

        key:这个共享内存段名字

        size:共享内存大小

        shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样                          的

返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1

 //comm.h                                                                                                                                                                                     1 #ifndef _COMM_H_ 2 #define _ COMM_H_3 #include <stdio.h>4 #include <sys/types.h>5 #include <sys/ipc.h>6 #include <sys/shm.h>7 8 #define PATHNAME "."9 #define PROJ_ID 0x666610 #define SIZE 409611 12 #endif                                                                                                                                                                                                       
    //sever.c1 #include "comm.h"2 #include <unistd.h>3 int main()4 {5   key_t k = ftok(PATHNAME, PROJ_ID);6   if(k < 0)7   {8     perror("ftok");9     return 1;10   }11   printf("%x\n", k);12   int shmid = shmget(k, SIZE, IPC_CREAT|IPC_EXCL|0644);13   if(shmid < 0)14   {15     perror("shmget");16     return 2;17   }18  19   return 0;20 }

运行这一段代码,便能成功创建一块共享内存,可以使用ipcs -m命令查看

shm的生命周期是随内核的,进程不主动删除或者用命令删除,共享内存就一直存在,直到关机重启。

释放这一块空间则是用命名ipcrm -m [shmid]

当然这块内存的释放也有函数可以使用,没必要在命令行进行这么麻烦的操作

shmctl函数

功能:用于控制共享内存

原型

        int shmctl(int shmid, int cmd, struct shmid_ds *buf);

参数

        shmid:由shmget返回的共享内存标识码

        cmd:将要采取的动作(有三个可取值)

        buf:指向一个保存着共享内存的模式状态和访问权限的数据结构

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

在上面创建的server.c中结尾加上这一段

sleep(10);shmctl(shm, IPC_RMID, NULL);sleep(10);    

运行这一段代码,可以看到共享内存一开始被创建,然后过了一会就被删除了

至此我们就完成了共享内存的创建与释放,那么接下来要解决的问题就是如何进行映射了

shmat函数

功能:将共享内存段连接到进程地址空间

原型

        void *shmat(int shmid, const void *shmaddr, int shmflg);

参数

        shmid:共享内存标识

        shmaddr:指定连接的地址

        shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY

返回值:成功返回一个指针,指向共享内存的第一个节;失败返回-1

    1 #include "comm.h"2 #include <unistd.h>3 #include <string.h>4 #include <sys/types.h>5 #include <sys/ipc.h>6 #include <sys/shm.h>7 int main()8 {9   key_t _key = ftok(PATHNAME, PROJ_ID);10   if(_key < 0)11   {12     perror("ftok");13     return -1;14   }15   printf("%x\n",_key);16   int shmid = 0;17   if((shmid = shmget(_key, SIZE, IPC_CREAT|IPC_EXCL|0644)) < 0)18   {19     perror("shmget");20     return -2;21   }22 23   printf("shmid: %d\n", shmid);24 25   printf("attach begin!\n");26   sleep(3);27   char* mem = shmat(shmid, NULL, 0);28   if(mem == (void*)-1)29   {30     perror("shmat");31     return 3;32   }                                                                                             33   printf("attach end!\n");34   sleep(3);35 36   shmctl(shmid, IPC_RMID, NULL);37 38   return 0;39 }

说明:

shmaddr为NULL,核心自动选择一个地址

shmaddr不为NULL且shmflg无SHM_RND标识,则以shmaddr为连接地址

shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHML BA的整数倍。公式:shmaddr - (shmaddr % SHML BA)

shmflg=SHM_RDONLY,表示连接操作用来只读共享内存

shmdt函数

功能:将共享内存段与当前进程脱离

原型

        int shmdt(const void *shmaddr);

参数

        shmaddr:由shmat所返回的指针

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

注意:将共享内存段与当前进程脱离不等于删除共享内存段

取消关联即在上面那段代码中的释放共享内存前加入

shmdt(mem);

即可取消进程与共享内存间的关联

实例代码
//comm.h1 #ifndef _COMM_H_ 2 #define _ COMM_H_3 #include <stdio.h>4 #include <sys/types.h>5 #include <sys/ipc.h>6 #include <sys/shm.h>7 8 #define PATHNAME "."9 #define PROJ_ID 0x666610 #define SIZE 409611 12 #endif        
//server.c1 #include "comm.h"2 #include <unistd.h>3 int main()4 {5   key_t k = ftok(PATHNAME, PROJ_ID);6   if(k < 0)7   {8     perror("ftok");9     return 1;10   }11   printf("%x\n", k);12   int shmid = shmget(k, SIZE, IPC_CREAT|IPC_EXCL|0644);13   if(shmid < 0)14   {15     perror("shmget");16     return 2;17   }18 19   printf("shmid: %d\n", shmid);20 21   sleep(5);22   char* mem = shmat(shmid, NULL, 0);23   while(1)24   {25   printf("client msg# %s\n", mem);26   sleep(1);                                                                                     27   }28   shmdt(mem);29 30   shmctl(shmid, IPC_RMID, NULL);31 32   return 0;33 }34 
//client.c1 #include "comm.h"2 #include <unistd.h>3 #include <string.h>4 int main()5 {6   key_t k = ftok(PATHNAME, PROJ_ID);7   if(k < 0)8   {9     perror("ftor");10     return 1;11   }12   int shmid = shmget(k, SIZE,0644);13   if(shmid < 0)14   {15     perror("shmget");16     return 2;17   }18 19   char* mem = shmat(shmid, NULL, 0);20 21   int i = 0;                                                                                    22   while(1)23   {24     mem[i] = 'A' + i;25     sleep(1);26     i++;27     mem[i] = 0;28   }29 30   shmdt(mem);31 32   return 0;33 }

可以看到我们实现了client端向server端通过共享内存进行信息的传输

共享内存的特点

1、共享内存是所有进程通信中速度最快的,因为它没有使用OS接口,拷贝次数减少

2、不提供任何保护机制(同步与互斥)

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

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

相关文章

OpenCV-28 全局二值化

一、形态学概念 什么是形态学&#xff1f; 1&#xff09;指一系列处理图像型状特征的图像处理技术 2&#xff09;形态学的基本思想是利用一直特殊的结构元&#xff08;本质上是卷积核&#xff0c;且这个卷积核的值只有1和0&#xff09;来测量或提取输入图像中相应的型状或特…

深入了解Go语言中的HTTP代理处理机制

Go语言&#xff0c;也被称为Golang&#xff0c;自2009年诞生以来&#xff0c;凭借其简洁、高效的特点&#xff0c;逐渐在系统编程、Web开发等多个领域崭露头角。在Web开发中&#xff0c;HTTP代理处理是常见的需求之一。本文将深入探讨Go语言中的HTTP代理处理机制。 HTTP代理是…

【Java 数据结构】LinkedList与链表

LinkedList与链表 1. ArrayList的缺陷2. 链表2.1 链表的概念及结构2.2 链表的实现 3. LinkedList的模拟实现4.LinkedList的使用4.1 什么是LinkedList4.2LinkedList的使用 5. ArrayList和LinkedList的区别 1. ArrayList的缺陷 上节课已经熟悉了ArrayList的使用&#xff0c;并且…

【linux】Linux项目自动化构建工具-make/Makefile

make/makefile 背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力 一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的规则来指定&#xff0c;哪些文件需要先编译&#xff0…

Java笔记 --- 二、Stream流

二、Stream流 结合Lambda表达式&#xff0c;简化集合、数组的操作 获取Stream流对象 单列集合获取Stream流 双列集合获取Stream流 数组获取Stream流 一堆零散的数据获取Stream流 Stream流的静态方法of的形参是一个可变参数&#xff0c;可以传递零散数据&#xff0c;也可以传递…

【计算机网络】IP协议及动态路由算法

对应代码包传送门 IP协议及动态路由算法代码包及思科模拟器资料说明 相关文章 【计算机网络】中小型校园网构建与配置 【计算机网络】Socket通信编程与传输协议分析 【计算机网络】网络应用通信基本原理 目的&#xff1a; 1、掌握IP协议&#xff0c;IP分片&#xff0c;DH…

04. OSPF

文章目录 一. 初识OSPF1.1. OSPF概述1.2. OSPF特性1.3. OSPF的专业术语1.4. OSPF维护的3张表1.5. OSPF报文类型1.6. OSPF的邻居状态 二. 实验题2.1. 实验1&#xff1a;点到点链路上的OSPF2.1.1. 实验目的2.1.2. 实验拓扑图2.1.3. 实验步骤&#xff08;1&#xff09;IP地址配置&…

【无标题】Gateway API 实践之(五)FSM Gateway 的会话保持功能

网关的会话保持功能是一种网络技术&#xff0c;旨在确保用户的连续请求在一段时间内被定向到同一台后端服务器。这种功能在需要保持用户状态或进行连续交互的场景中特别重要&#xff0c;例如在维护在线购物车、保持用户登录状态或处理多步骤事务时。 会话保持通过提供一致的用…

java判空工具类 java判断对象属性是否全部为空

java判空工具类 java判断参数是否为空工具类 java判断对象属性是否全部为空 。 可以判断字符串数组&#xff0c;字符串类型&#xff0c;List对象集合&#xff0c;Map集合map<String,object>&#xff0c;map和多个String参数&#xff0c;对象类型&#xff0c;是否为空。…

数据结构C++队列(数组模拟)

队列也是比较简单的数据结构了&#xff0c;队列的特点是先进先出 下面代码中hh是队头&#xff0c;tt是队尾。 默认是从队尾插入数据&#xff0c;队头弹出数据。 代码中的数据结构可以使用这图片来解释&#xff0c;整个区间是数组q。hh和tt分别控制队头和队尾。 例题&#x…

AI作画工具 stable-diffusion-webui 一键安装工具(A1111-Web-UI-Installer)

安装 下载最新版本确保你的 NVIDIA 显卡驱动程序是最新的&#xff08;起码不能太老&#xff09;启动安装程序在欢迎屏幕上单击下一步在屏幕上&#xff0c;选择要安装的内容如果你已经安装了 Python 3.10 和 Git&#xff0c;那么可以取消选中如果你不知道这些是什么&#xff0c…

[01 LinuxShell ] 清华大学电子系科协软件部2023暑期培训

清华大学电子系科协软件部2023暑期培训_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV11N4y187ZE/?spm_id_from333.1007.top_right_bar_window_custom_collection.content.click&vd_source3ef6540f8473c7367625a53b7b77fd66 本视频为清华大学电子系科协软件部2023…

简单介绍----微服务和Spring Cloud

微服务和SpringCloud 1.什么是微服务&#xff1f; 微服务是将一个大型的、单一的应用程序拆分成多个小型服务&#xff0c;每个服务负责实现特定的业务功能&#xff0c;并且可以通过网络通信与其他服务通信。微服务的优点是开发更灵活&#xff08;不同的微服务可以使用不同的开…

nginx使用stream模块代理端口

今天原本准备将本地金仓的54321端口进行代理的&#xff0c;但是发现代理后总是无法访问。后来突然发现之前使用nginx代理的是一个地址而不是端口。因此做以下笔记用来做记录。 一、stream安装与配置 假设nginx在usr/local/nginx中 1. 测试当前nginx是否有stream模块 ./usr/…

FPGA 通过 UDP 以太网传输 JPEG 压缩图片

FPGA 通过 UDP 以太网传输 JPEG 压缩图片 简介 在 FPGA 上实现了 JPEG 压缩和 UDP 以太网传输。从摄像机的输入中获取单个灰度帧&#xff0c;使用 JPEG 标准对其进行压缩&#xff0c;然后通过UDP以太网将其传输到另一个设备&#xff08;例如计算机&#xff09;&#xff0c;所有…

代码随想录算法刷题训练营day17

代码随想录算法刷题训练营day17&#xff1a;LeetCode(110)平衡二叉树 LeetCode(110)平衡二叉树 题目 代码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(…

计算机二级C语言的注意事项及相应真题-6-程序填空

目录 51.将参数num按升序插入到数组xx中52.在数组中找出两科成绩之和最高的学生并返回其在数组中的下标53.删除所有串长超过k的字符串&#xff0c;输出剩下的字符串54.根据所给的一组学生的成绩&#xff0c;计算出平均成绩&#xff0c;并计算低于平均成绩的学生的平均成绩55.将…

AlexNet,ZFNet详解

1 AlexNet 网络结构 对于AlexNet网络来说&#xff0c;因为当时资源环境受限&#xff0c;他从第一步卷积开始就把一个图像分到两个GPU上训练&#xff0c;然后中间进行组合最后进行融合成全连接成1000个置信度 1 得到一张3x224x224的图像&#xff0c;然后进行11x11的卷积&…

山海鲸智慧医疗解决方案:让医疗数据说话

在医疗领域&#xff0c;数据可视化对于提高诊疗效率、辅助医学研究和提升患者就医体验具有重要意义。作为山海鲸可视化软件的开发者&#xff0c;我们致力于利用先进的数据可视化技术&#xff0c;为医疗行业提供高效、智能的解决方案&#xff0c;本篇文章就带大家一起了解一下这…

【Linux】开始使用 vim 吧!!!

Linux 1 what is vim &#xff1f;2 vim基本概念3 vim的基本操作 &#xff01;3.1 vim的快捷方式3.1.1 复制与粘贴3.1.2 撤销与剪切3.1.3 字符操作 3.2 vim的光标操作3.3 vim的文件操作 总结Thanks♪(&#xff65;ω&#xff65;)&#xff89;感谢阅读下一篇文章见&#xff01;…