Linux下实现共享内存的两种机制(附源码)

news2024/11/14 13:37:14

 

START

 

Hello 大家好。

今天来讲一下Linux进程通信中重要的通信方式:共享内存作为Linux软件开发攻城狮,进程间通信是必须熟练掌握的重要技能,而共享内存是在程序开发中常用的也是重要的一种进程间通信方式。

下面我们就来聊一聊Linux下进程间如何实现共享内存通信,有哪些方式?

1、基本概念

UNIX Linux

UNIXLinux是两种不同的操作系统,它们的主要区别在以下几个方面:

历史:UNIX是最早的商业化操作系统之一,最初由贝尔实验室开发,而Linux则是由Linus Torvalds1991年开发的开源操作系统。

源代码:UNIX的源代码是私有的,需要购买授权才能使用和修改,而Linux是开源的,任何人都可以自由地访问、使用和修改其源代码。

可移植性:由于UNIX的代码是私有的,因此它们在不同的硬件平台之间的可移植性较差。而Linux的源代码是开放的,因此它可以在多种硬件平台上运行。

发行版:UNIX有多个商业和非商业版本,如SolarisAIXHP-UX等,每个版本都有自己的特点和功能。而Linux则有许多不同的发行版,如UbuntuDebianRed HatFedora等。

命令行工具:UNIXLinux有许多相同的命令行工具和命令,如lsgrepawk等,但也有一些不同之处。

总的来说,UNIXLinux都是基于UNIX哲学的操作系统,但它们在源代码、可移植性、发行版和命令行工具等方面有所不同。

System V POSIX

System VPOSIX是两种不同的操作系统标准,它们的区别在以下几个方面:

历史背景:System V最初是由AT&T开发的UNIX版本,而POSIXIEEE为了保证不同UNIX系统的兼容性而开发的标准。

体系结构:System V是一种具体的操作系统,而POSIX则是一种操作系统接口标准。因此,System V具有更多的操作系统特定功能,而POSIX的接口更为通用,适用于多种不同类型的UNIX系统。

文件系统:System VPOSIX的文件系统不同。System V使用名为“inode”的数据结构来描述文件和目录,而POSIX则使用名为文件描述符的整数来表示打开的文件。

ShellSystem VPOSIXShell也不同。System VShellBourne Shell,而POSIXShellBourne-Again Shellbash)。

网络支持:System VPOSIX的网络支持也不同。System V使用TCP/IP协议栈,而POSIX使用套接字(socket)接口。

2System V IPC POSIX IPC

System V IPCInterprocess Communication)和POSIX IPC都是用于在不同进程间进行通信的机制,但它们之间有几个区别:

编程接口:System V IPCPOSIX IPC的编程接口不同。System V IPC使用IPC对象(如信号量、共享内存和消息队列)来实现进程间通信,而POSIX IPC使用命名对象(如命名信号量、命名共享内存和命名管道)。

可移植性:POSIX IPC是由IEEE POSIX标准定义的,因此POSIX IPC是可移植的,可在不同的操作系统上使用。而System V IPC是由System V操作系统提供的,因此不同的操作系统可能实现不同,因此在跨平台时可能会有问题。

接口和实现:System V IPC的接口和实现是紧密耦合的,而POSIX IPC的接口和实现是松散耦合的。这意味着在POSIX IPC中,接口和实现是独立的,因此可以在实现中进行更改,而不影响接口,这使得在不同的系统上实现相同的接口变得更容易。

特性:System V IPC提供的特性比POSIX IPC多,例如,System V IPC提供了消息队列,而POSIX IPC则没有。另一方面,POSIX IPC提供了诸如命名管道之类的特性,而System V IPC则没有。

综上所述,System V IPCPOSIX IPC都有其优点和缺点。在选择使用哪种IPC机制时,需要根据具体应用场景和需求进行权衡。

3、共享内存实现方式

Linux下,共享内存可以使用System V IPC机制或POSIX IPC机制实现。

使用System V IPC机制:

使用shmget()函数创建共享内存区域并获取其标识符。使用shmat()函数将共享内存区域附加到进程地址空间中。使用shmdt()函数将共享内存区域从进程地址空间中分离。使用shmctl()函数控制共享内存区域的属性和状态。

使用POSIX IPC机制:

使用shm_open()函数创建共享内存区域并获取其文件描述符。使用ftruncate()函数调整共享内存区域的大小。使用mmap()函数将共享内存区域映射到进程地址空间中。使用munmap()函数解除共享内存区域与进程地址空间的映射关系。使用shm_unlink()函数删除共享内存区域的文件名并释放资源。

System V IPC机制实现共享内存

以下是一个使用System V IPC机制实现共享内存的简单例程,它展示了如何创建、附加和分离共享内存区域。

#include <stdio.h>

#include <stdlib.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <string.h>



#define SHM_SIZE 1024 // 共享内存大小



int main() {

    int shmid;

    char *shmaddr;

    char s8ReadBuf[1024] = {0};

    key_t key = ftok(".", 's'); // 获取共享内存标识符



    if (key == -1) {

        perror("ftok");

        exit(1);

    }



    // 创建共享内存区域

    shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);

    if (shmid == -1) {

        perror("shmget");

        exit(1);

    }



    // 将共享内存区域附加到进程地址空间中

    shmaddr = shmat(shmid, NULL, 0);

    if (shmaddr == (char *) -1) {

        perror("shmat");

        exit(1);

    }



#if 1

    // 在共享内存中写入数据

    strncpy(shmaddr, "Hello, world!", SHM_SIZE);

#else

    // 读数据

    // memcpy(s8ReadBuf, shmaddr, 1024);

    // printf("s8ReadBuf:%s\n", s8ReadBuf);

#endif



    // 分离共享内存区域

    if (shmdt(shmaddr) == -1) {

        perror("shmdt");

        exit(1);

    }



    return 0;

}

在上面的例程中,我们首先使用ftok()函数生成一个key值作为共享内存的标识符。然后使用shmget()函数创建共享内存区域,shmaddr指向共享内存区域的起始地址。最后使用shmdt()函数分离共享内存区域。

POSIX IPC机制实现共享内存

以下是一个使用POSIX IPC机制实现共享内存的简单例程,它展示了如何创建、映射和解除映射共享内存区域。

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <sys/mman.h>

#include <unistd.h>

#include <string.h>



#define SHM_SIZE 1024 // 共享内存大小

#define SHM_NAME "/myshm" // 共享内存名称



int main() {

    int fd;

    char *shmaddr;

    char s8ReadBuf[1024] = {0};

    const char *msg = "Hello, world!";



    // 创建共享内存区域

    fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);

    if (fd == -1) {

        perror("shm_open");

        exit(1);

    }



    // 调整共享内存区域的大小

    if (ftruncate(fd, SHM_SIZE) == -1) {

        perror("ftruncate");

        exit(1);

    }



    // 映射共享内存区域到进程地址空间中

    shmaddr = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    if (shmaddr == MAP_FAILED) {

        perror("mmap");

        exit(1);

    }



#if 1

    // 在共享内存中写入数据

    strncpy(shmaddr, msg, SHM_SIZE);

#else

    // 读数据

    // memcpy(s8ReadBuf, shmaddr, 1024);

    // printf("s8ReadBuf:%s\n", s8ReadBuf);

#endif

    // 解除共享内存区域与进程地址空间的映射关系

    if (munmap(shmaddr, SHM_SIZE) == -1) {

        perror("munmap");

        exit(1);

    }



    // 删除共享内存区域的文件名并释放资源

    if (shm_unlink(SHM_NAME) == -1) {

        perror("shm_unlink");

        exit(1);

    }



    return 0;

}

在上面的例程中,我们使用shm_open()函数创建一个共享内存区域,然后使用ftruncate()函数调整共享内存区域的大小。接着,我们使用mmap()函数将共享内存区域映射到进程地址空间中,并使用strncpy()函数在共享内存中写入数据。最后,我们使用munmap()函数解除共享内存区域与进程地址空间的映射关系,并使用shm_unlink()函数删除共享内存区域的文件名并释放资源。

小结

通过上面的示例希望对小伙伴们在共享内存通信编程中有所帮助,学会如何使用共享内存通信,并灵活运用于日常的编程中。共享内存方式的通信必须熟练掌握与应用。

END

 

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

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

相关文章

【C++】string类的深浅拷贝问题

string类的深浅拷贝问题 浅拷贝问题构造/析构函数拷贝构造/赋值运算符重载的多种写法 浅拷贝问题 我们知道&#xff0c;定义一个类的时候&#xff0c;如果我们没有写构造&#xff0c;拷贝构造&#xff0c;赋值运算符重载&#xff0c;析构方法的话&#xff0c;编译器会自动生成。…

Django学习笔记001之创建项目

学习目标&#xff1a; 了解前端后台框架 掌握vs搭建Django环境 学习内容 1.背景学习 优缺点&#xff1a; 2.vs搭建Django开发环境 2.1. 准备vscode工具 可以从github上获取&#xff1a;https://github.com/microsoft/vscode。 2.2. 构建python虚拟环境 使用的命令是pyth…

微分方程数值解法(Runge-Kutta法PLC实现)

微分方程数值解法之欧拉法请参看下面的博客文章: 微分方程数值解法(PID仿真用一阶被控对象库PLC算法实现)_数学微积分算法plc编程实例_RXXW_Dor的博客-CSDN博客微分方程除极特殊情况外,大部分不可能求出它的精确解,只能用各种近似方法得到满足一定精度的近似解,微分方程由…

CTA进网检验要求修订原则和变更说明 SAR新国标在2024年正式实施

《进网检验要求文件》 实行定期及动态更新原则&#xff0c;其中检测项目应能体现进网监管的职责定位。 第一部分 基本功能性能 第二部分 空间性能 SAR 新版进网检验要求细化了各场景的测试距离&#xff1a; SAR新要求的实施日期&#xff1a; 第二部分 空间性能 EMC 第二部分 空…

【MySQL】查询中,NULL值转换为空字符串

系列文章 C#底层库–MySQLBuilder脚本构建类&#xff08;select、insert、update、in、带条件的SQL自动生成&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129179216 C#底层库–MySQL数据库操作辅助类&#xff08;推荐阅读&#xff0…

【browserify】一步步教你学会browserify

https://www.cnblogs.com/fsg6/p/13139627.html Browserify browserify的官网是http://browserify.org/&#xff0c;他的用途是将前端用到的众多资源&#xff08;css,img,js,…) 打包成一个js文件的技术。 比如在html中引用外部资源的时候&#xff0c;原来我们可能这样写 &l…

C嘎嘎~~ [类 上篇]

类 上篇 1.面向过程和面向对象的认识2.类的引入3.类的定义4.类的访问限定符和封装4.1封装4.2访问限定符 5.类的作用域 1.面向过程和面向对象的认识 面向过程 和 面向对象的区别: 面向过程关注的是过程, 而面向对象关注的是对象之间的关系, 交互. C语言是面向过程的, 而C是面向对…

webshell gif图片文件绕过

目录页/dev/index. php允许GIF上传。尝试上传不同的文件类型将被拒绝。 这可以通过首先上传合法的GIF文件来绕过。使用了一个小的GIF https://giphy.com/gifs/obi-won-hvE0PhVAnGQAo 下载一个小的字节图片测试 上传文件并使用Burpsuite捕获请求。尝试上传时的请求应类似于下…

淘宝天猫店铺新品如何运营?

新品在店铺运营过程中是十分重要的部分&#xff0c;你知道新品在店铺运营中有何作用&#xff1f;了解新品运营机制吗&#xff1f;今天就来快速了解关于新品的知识点。 新品在店铺运营的角色&#xff1a; 01、商品生命周期有限 商品的普遍生命周期在3个月左右&#xff0c;3个…

Codeforces Round 867 (Div. 3)

Problem - E - Codeforces 思路&#xff1a; 首先&#xff0c;如果n为奇数&#xff0c;中间那个数无法调整&#xff0c;所以只考虑偶数只有26个字母&#xff0c;我们用cnt[]记录每个字母需要交换的对数。设maxn为交换对数最多的字母。显然&#xff0c;如果cnt[maxn]>n/2,显…

速锐得解码奔驰CAN数据应用于海外车联网远程控制与防盗系统

人们常说&#xff0c;奔驰征服一切&#xff0c;你征服奔驰。速锐得帮你征服奔驰的数据。 前日&#xff0c;有个海外客户&#xff0c;问我们做了奔驰哪些数据&#xff0c;他们需要一个车联网的远程控制系统&#xff0c;用于管理他们的车队。客户比较豪横&#xff0c;大多数都是…

大数据管理中心规划设计方案(ppt可编辑)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除。 统一汇聚 推动业务数据协同5 价值提炼 支撑精准服务与科学管理6 实时感知 辅助城市治理高效运行7 大数据资源平台目标体系规划11 建设目标与思路12 使能高效协同&#xff0…

榜上有名 | 创宇盾荣登“2023 IT市场权威榜单”!

4月20日&#xff0c;已连续成功举办23届的IT市场年会在北京举行&#xff0c;作为权威咨询机构赛迪主办&#xff0c;中国IT业界延续时间最长的年度盛会之一&#xff0c;“2023 IT市场年会”隆重发布重磅权威榜单。 创宇盾作为云防护领域专业防护产品&#xff0c;在国家经济产业…

C++的默认成员函数

上一次我们说到了C的类&#xff0c;我们还知道在C的类中可以写函数&#xff0c;而且这个函数也属于这个类&#xff0c;我们可以直接使用这个类的对象去调用这个函数。 今天我们来看一下C的六个默认成员函数(这里说是6个&#xff0c;但是重要的只有4个) 构造函数 在C语言中&a…

Raft 共识算法3-日志复制

Raft 共识算法3-日志复制 Raft算法中译版地址&#xff1a;https://object.redisant.com/doc/raft%E4%B8%AD%E8%AF%91%E7%89%88-2023%E5%B9%B44%E6%9C%8823%E6%97%A5.pdf 英原论文地址&#xff1a;https://raft.github.io/raft.pdf Etcd Assistant 是一款 etcd 可视化管理软件&a…

idea使用 ( 一 ) 安装及初步使用

1.介绍 1.1.什么是 IDE 集成开发环境&#xff08;IDE&#xff0c;Integrated Development Environment &#xff09;是用于提供程序开发环境的应用程序&#xff0c;一般包括代码编辑器、编译器、调试器和图形用户界面]等工具。简单说就是开发工具&#xff0c;java开发中常用的…

一文读懂数据安全分级分类

目录 为什么要分级分类&#xff1f; 通用数据分级分类框架 数据分类 数据分类的常用方法 数据分类流程 数据分级 数据分级的常用方法 数据定级流程 行业数据安全分级分类指南 金融行业 电信行业 政务数据 健康医疗 企业实践 附录&#xff1a;数据分级分类大合集…

CAD格式交换全能:CAD DLL 15.0 Crack

添加对 SLDASM、FSAT、SAB、SMT、IPT 和 IFC 格式的支持。 2023 年 4 月 25 日 - 16:27 新版本 特征 改进的 3D&#xff1a; 打开 3D 文件时提高了速度。改进了对 SAT、STEP、SLDPRT、X_T、X_B、OBJ 格式的读取。添加了对 SLDASM、FSAT、SAB、SMT、IPT、IFC 格式的支持。添加了…

聊聊 maven的版本号version 以及maven指定版本号范围写法

1. 版本管理&#xff08;version&#xff09; 说了那么多废话&#xff0c;什么是版本管理&#xff1f;首先&#xff0c;一个健康的项目&#xff0c;通常有一个长期、合理的版本演变过程。版本管理是指项目整体版本的演变过程管理&#xff0c;就比如从1.0-SNAPSHOT --> 1.0 …

懂这3件事情,就能成功实施MES管理系统实现“数字化”工厂

当前&#xff0c;很多企业对MES管理系统需求旺盛&#xff0c;但是&#xff0c;要保证MES管理系统能够有效地实施&#xff0c;实现精益化管理&#xff0c;打造出一个“数字化”工厂&#xff0c;公司在实施MES管理系统之前&#xff0c;还必须弄明白为什么要MES管理系统、MES有什么…