通过共享内存进行通信(嵌入式学习)

通过共享内存进行通信

  • 概念
  • 特点
  • 函数
  • 示例代码

概念

在Linux中,共享内存是一种进程间通信(IPC)机制,允许多个进程共享同一块内存区域。这种通信方式可以提供高效的数据传输,特别适用于需要频繁交换数据的场景。
在这里插入图片描述

IO间进程通信请点击这里——》IO进程间的通信详解(嵌入式学习)

IO进程间的通信详解(嵌入式学习)《——这里
IO进程间的通信详解(嵌入式学习)《——这里这里里

要在Linux中使用共享内存,需要以下步骤:

  1. 创建共享内存段:使用shmget系统调用创建一个共享内存段。该调用需要指定共享内存标识符、内存大小和权限等参数。如果共享内存已经存在,则可以使用shmget的返回值获取该共享内存段的标识符。

  2. 连接共享内存段:使用shmat系统调用将共享内存段连接到当前进程的地址空间中。shmat需要指定共享内存段的标识符和附加选项。成功连接后,shmat将返回指向共享内存段的指针。

  3. 使用共享内存:一旦连接到共享内存段,进程可以像使用普通内存一样使用共享内存。可以读取、写入数据,进行同步操作等。

  4. 分离共享内存段:当进程不再需要使用共享内存段时,可以使用shmdt系统调用将其与当前进程分离。这将使得共享内存段不再对该进程可见,但不会删除该共享内存段。

  5. 删除共享内存段:当所有进程都不再需要使用共享内存段时,可以使用shmctl系统调用删除该共享内存段。这将释放共享内存并将其从系统中删除。

要使用共享内存,需要包含<sys/ipc.h><sys/shm.h>头文件,并链接到-lrt库。

请注意,共享内存需要进程之间进行适当的同步和互斥操作,以避免竞态条件和数据损坏。通常,使用信号量或其他同步机制来控制对共享内存的访问。

特点

共享内存在进程间通信(IPC)中具有以下特点:

  1. 高效性:共享内存提供了一种高效的数据传输方式,因为数据直接存储在共享内存中,而不需要进行进程间的数据复制。这比其他IPC机制(如管道或消息队列)更快。

  2. 大容量:共享内存可以提供较大的内存空间供多个进程共享。这使得它特别适用于需要频繁交换大量数据的场景。

  3. 实时性:由于共享内存的直接访问性质,进程可以即时地读取和写入共享内存中的数据,使得共享内存在实时应用程序中非常有用。

  4. 简单性:相对于其他IPC机制,使用共享内存进行通信相对较简单。进程可以像访问本地内存一样直接读写共享内存,无需复杂的读取或写入操作。

  5. 零拷贝:共享内存的实现方式通常使用"零拷贝"技术,即数据从一个进程的地址空间传输到另一个进程的地址空间时,避免了数据的中间复制,提高了数据传输的效率。

然而,共享内存也存在一些注意事项:

  1. 同步问题:由于多个进程可以同时访问共享内存,必须进行适当的同步操作,以避免竞态条件和数据不一致的问题。通常使用信号量、互斥锁等同步机制来控制对共享内存的访问。

  2. 生命周期管理:在使用共享内存时,需要确保在合适的时间创建、连接、分离和删除共享内存段。如果没有适当管理共享内存的生命周期,可能会导致内存泄漏或无法访问共享内存的情况。

  3. 安全性:共享内存不提供进程间的安全性保护机制,因此必须确保对共享内存的访问受到适当的权限控制,防止未经授权的进程访问共享内存。

综上所述,共享内存是一种高效、快速的进程间通信机制,适用于需要高吞吐量和实时性的应用程序。但在使用时需要注意同步、生命周期管理和安全性等方面的问题。

函数

在Linux中,可以使用以下函数来操作共享内存:

  1. int shmget(key_t key, size_t size, int shmflg)

    • 该函数创建或打开一个共享内存段。
    • 参数key是用于标识共享内存段的键值。
    • 参数size指定共享内存段的大小。
    • 参数shmflg指定一些标志选项,例如权限和创建标志。
    • 返回值是共享内存段的标识符(非负整数),如果失败则返回-1。
  2. void *shmat(int shmid, const void *shmaddr, int shmflg)

    • 该函数将共享内存段连接到当前进程的地址空间。
    • 参数shmid是共享内存段的标识符。
    • 参数shmaddr指定要连接的地址,通常设置为NULL,让内核选择一个可用地址。
    • 参数shmflg指定一些标志选项,例如读写权限和标志。
    • 返回值是指向共享内存段的指针,如果失败则返回-1
  3. int shmdt(const void *shmaddr)

    • 该函数将共享内存段与当前进程分离。
    • 参数shmaddr是要分离的共享内存段的指针。
    • 返回值为0表示成功,-1表示失败。
  4. int shmctl(int shmid, int cmd, struct shmid_ds *buf)

    • 该函数用于控制共享内存段的属性。
    • 参数shmid是共享内存段的标识符。
    • 参数cmd指定要执行的命令,如删除共享内存段。
    • 参数buf是一个指向struct shmid_ds结构的指针,用于获取或设置共享内存段的属性。
    • 返回值为0表示成功,-1表示失败。

这些函数在<sys/ipc.h><sys/shm.h>头文件中声明。要使用共享内存,您还需要链接到-lrt库。

这只是共享内存函数的基本介绍,您可以参考相关文档和教程以获取更详细的信息和示例代码。

示例代码

以下是一个简单的示例代码,展示如何使用共享内存在两个进程之间进行通信:
在这里插入图片描述

进程A(写入数据到共享内存):

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHM_SIZE 1024

int main() {
    int shmid;
    key_t key;
    char *shm_ptr;

    // 生成共享内存的key
    key = ftok("/tmp", 'R');
    if (key == -1) {
        perror("ftok");
        exit(1);
    }

    // 创建共享内存段
    shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);
    if (shmid == -1) {
        perror("shmget");
        exit(1);
    }

    // 连接共享内存段到当前进程的地址空间
    shm_ptr = shmat(shmid, NULL, 0);
    if (shm_ptr == (char *)-1) {
        perror("shmat");
        exit(1);
    }

    // 写入数据到共享内存
    sprintf(shm_ptr, "Hello, shared memory!");

    // 分离共享内存段
    if (shmdt(shm_ptr) == -1) {
        perror("shmdt");
        exit(1);
    }

    return 0;
}

进程B(从共享内存中读取数据):

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHM_SIZE 1024

int main() {
    int shmid;
    key_t key;
    char *shm_ptr;

    // 获取共享内存的key
    key = ftok("/tmp", 'R');
    if (key == -1) {
        perror("ftok");
        exit(1);
    }

    // 获取共享内存段的标识符
    shmid = shmget(key, SHM_SIZE, 0666);
    if (shmid == -1) {
        perror("shmget");
        exit(1);
    }

    // 连接共享内存段到当前进程的地址空间
    shm_ptr = shmat(shmid, NULL, 0);
    if (shm_ptr == (char *)-1) {
        perror("shmat");
        exit(1);
    }

    // 从共享内存中读取数据并打印
    printf("Message from shared memory: %s\n", shm_ptr);

    // 分离共享内存段
    if (shmdt(shm_ptr) == -1) {
        perror("shmdt");
        exit(1);
    }

    // 删除共享内存段
    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
        perror("shmctl");
        exit(1);
    }

    return 0;
}

在这个示例中,进程A创建了一个大小为1024字节的共享内存段,并写入了一条消息到共享内存中。进程B通过共享内存的键获取到该共享内存段的标识符,并连接到当前进程的地址空间,然后读取共享内存中的数据并打印出来。最后,进程B从共享内存中分离,并使用shmctl函数将共享内存段删除。

请注意,在实际使用中,需要确保进程A和进程B以正确的顺序执行,以便正确地进行共享内存的创建、连接和分离。此外,需要进行适当的同步和互斥操作,以避免竞态条件和数据损坏。

编译和运行示例代码时,需要使用gcc编译器,并链接到-lrt库:

gcc processA.c -o processA -lrt
gcc processB.c -o processB -lrt

然后分别运行进程A和进程B:

./processA
./processB

进程B会输出从共享内存中读取的消息。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

为CentOs配置静态IP

目录 第一步&#xff1a;查看物理机IP 第二步&#xff1a;虚拟机网络设置 点击虚拟机->编辑虚拟机设置 第三步&#xff1a;CentOS网络配置文件 第四步&#xff1a;重启网络 第五步&#xff1a;测试网络 为什么要设置静态IP 在安装好CentOS虚拟机以后&#xff0c;一般我…

程序替换原理

文章目录 一、程序替换 一、程序替换 程序替换用于将当前进程的用户空间的代码和数据全部替换为新程序的代码和数据&#xff0c;程序替换不会创建新进程&#xff0c;而是用当前进程执行新程序的代码&#xff0c;fork 创建子进程后&#xff0c;子进程默认执行的是父进程的代码&…

vue2和vue3的渲染过程简述版

文章目录 vue2渲染过程vue3渲染过程优化和扩充 vue2和vue3对比 vue2渲染过程 在Vue 2的渲染过程中&#xff0c;包括以下几个关键步骤&#xff1a; 解析模板&#xff1a;Vue 2使用基于HTML语法的模板&#xff0c;首先会将模板解析成抽象语法树&#xff08;AST&#xff09;&…

K8s 部署 Apache Kudu 集群

一、K8s 部署 Apache Kudu 集群 安装规划 组件replicaskudu-master3kudu-tserver3 1. 创建命名空间 vi kudu-ns.yamlapiVersion: v1 kind: Namespace metadata:name: apache-kudulabels:name: apache-kudukubectl apply -f kudu-ns.yaml查看命名空间&#xff1a; kubectl …

JUC高级-0614

5.LockSupport与线程中断 5.1 线程中断 蚂蚁金服面试题&#xff1a;如何中等一个线程&#xff0c;如何停止一个线程什么是中断机制 首先&#xff1a;一个线程不应该由其他线程来强制中断或停止&#xff0c;而是应该由线程自己自行停止。所以&#xff0c;Thread.stop, Thread.…

【spring源码系列-06】refresh中obtainFreshBeanFactory方法的执行流程

Spring源码系列整体栏目 内容链接地址【一】spring源码整体概述https://blog.csdn.net/zhenghuishengq/article/details/130940885【二】通过refresh方法剖析IOC的整体流程https://blog.csdn.net/zhenghuishengq/article/details/131003428【三】xml配置文件启动spring时refres…

十个实用MySQL函数

函数 0. 显示当前时间 命令&#xff1a;。 作用: 显示当前时间。 应用场景: 创建时间&#xff0c;修改时间等默认值。 例子&#xff1a; 1. 字符长度 命令&#xff1a;。 作用: 显示指定字符长度。 应用场景: 查看字符长度时。 例子&#xff1a; 2. 日期格式化 命令…

面试---简历

项目 1.1、商品管理 新增商品 同时插入商品对应的使用时间数据&#xff0c;需要操作两张表&#xff1a;product&#xff0c;product_usetime。在productService接口中定义save方法&#xff0c;该方法接受一张Dto对象&#xff0c;dto对象继承自product类&#xff0c;并将prod…

Stable Diffusion webui 基础参数学习

哈喽&#xff0c;各位小伙伴们大家好&#xff0c;最近一直再研究人工智能类的生产力&#xff0c;不得不说随着时代科技的进步让人工智能也得到了突破性的发展。而小编前段时间玩画画也是玩的不可自拔&#xff0c;你能想想得到&#xff0c;一个完全不会画画的有一天也能创作出绘…

【测试基础01】

软件测试 一、软件测试基本概念(1)、软件测试的定义(2)、软件错误的定义(3)、测试分类 二、需求文档的评审三、软件测试计划(1)、测试范围(2)、测试环境(3)、测试策略(4)、测试管理(5)、测试风险(6)、模板 一、软件测试基本概念 (1)、软件测试的定义 软件测试是从前期需求文档…

freeswitch 使用 silero-vad 静音拆分使用 fastasr 识别

silero-vad 在git 的评分挺高的测试好像比webrtc vad好下面测试下 silero-vad 支持c 和py 由于识别c的框架少下面使用py 以下基于python3.8torch1.12.0torchaudio 1.12.0 1.由于fastasr 需要16k 所以 将freeswitch的实时音频mediabug 8k转成16k 用socket传到py 模块代码…

ChatGLM-6B 在 ModelWhale和本地 平台的部署与微调教程

ChatGLM-6B 在 ModelWhale 平台的部署与微调教程 工作台 - Heywhale.com ChatGLM-6B 介绍 ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型&#xff0c;基于 General Language Model (GLM) 架构&#xff0c;具有 62 亿参数。结合模型量化技术&#xff0c;用户可以在消费…

高压放大器在介电材料测试中的应用

介电材料测试是一项重要的材料性能测试&#xff0c;它涉及到物理学、化学、材料科学等多个学科领域。高压放大器是介电材料测试中的一种重要设备&#xff0c;它可以放大微弱的电信号&#xff0c;提高测试的准确性和精度。下面将详细介绍高压放大器在介电材料测试中的应用。 图&…

Web前端开发技术储久良第三版课后选择答案(1-10章)

P16-第1章 练习与实验答案 练习1 1.选择题 【1】Html是一种&#xff08;&#xff09;语言。 【A】编译型 【B】超文本标记 【C】高级程序设计 【D】面向对象编程【2】世界上第一个网页是()。 【A】http://www.w3c.org 【B】http:/info.cern.ch 【C】http://www.microsoft.com…

【论文阅读】(2023.06.09-2023.06.18)论文阅读简单记录和汇总

(2023.06.09-2023.06.12)论文阅读简单记录和汇总 2023/06/09&#xff1a;虽然下周是我做汇报&#xff0c;但是到了周末该打游戏还是得打的 2023/06/12&#xff1a;好累好困&#xff0c;现在好容易累。 目录 &#xff08;TCSVT 2023&#xff09;Facial Image Compression via …

2021电工杯数学建模B题解题思路

目录 一、前言 二、问题背景 三、具体问题 四、解题思路 &#xff08;一&#xff09;整体思路 &#xff08;二&#xff09;问题一 &#xff08;三&#xff09;问题二 &#xff08;四&#xff09;问题三 &#xff08;五&#xff09;问题四 &#xff08;六&#xff09;…

使用parcel搭建threejs开发环境

一、什么是parcel parcel官网&#xff1a;https://www.parceljs.cn/ Parcel是一个快速、零配置的Web应用打包器&#xff0c;可将JavaScript、CSS、HTML和图像等静态文件打包到一个捆绑文件中。它的主要目标是简化Web应用程序的打包过程&#xff0c;使开发人员可以更快速地创建…

【深度学习】1 感知机(人工神经元)

认识感知机 感知机接收多个输入信号&#xff0c;输出一个信号 感知机的信号只有“流/不流”(1/0)两种取值 0对应“不传递信号”&#xff0c;1对应“传递信号”。 输入信号被送往神经元时&#xff0c;会被分别乘以固定的权重。神经元会计算传送过来的信号的综合&#xff0c;只有…

怎么利用代理IP优化网络爬虫

网络爬虫会自动扫描互联网&#xff0c;搜集大量数据并将它们组织起来。但是&#xff0c;许多网站都采取了反爬虫策略&#xff0c;限制了网络爬虫的活动。这时候&#xff0c;代理IP就起到了关键作用。 一、代理ip在网络爬虫中的作用 代理ip爬虫中使用代理IP有很多好处。首先&…

OpenCV 笔记_3

文章目录 笔记_3直方图匹配(直方图规定化) 主要针对单通道图像模板匹配matchTemplate 模板匹配函数 图像卷积filter2D 卷积函数 过滤器图像噪声的产生cvflann::rand_double 产生随机浮点数在&#xff08;0~1&#xff09;之间cvflann::rand_int 产生随机整数在&#xff08;0~RAN…