Linux系统编程之共享内存

概述

        在Linux系统中,共享内存也是一种高效的进程间通信机制,允许两个或多个进程共享同一块物理内存区域。通过这种方式,不同进程可以直接访问和操作相同的数据,从而避免了数据的复制。由于数据直接在内存中共享,没有额外的数据传输过程,因此速度非常快。虽然共享内存本身提供了快速的数据交换方式,但它并不提供同步机制。这意味着,需要我们自己实现同步措施以防止竞态条件。

API接口

        在Linux中,主要通过以下几个API接口来实现共享内存机制。

        1、shmget:用于创建一个新的共享内存段,或获取一个已存在的共享内存段。其函数原型如下。

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

        各个参数和返回值的含义如下。

        key:标识共享内存段的键值,通常使用ftok函数生成。

        size:共享内存段的大小,以字节为单位。

        shmflg:权限标志和创建标志(比如IPC_CREAT、IPC_EXCL等),以及访问权限。

        返回值:成功时,返回共享内存标识符。失败时返回-1,可通过errno获取具体的错误代码。

        2、shmat:将共享内存段连接到调用进程的地址空间。其函数原型如下。

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

        各个参数和返回值的含义如下。

        shmid:由shmget函数返回的共享内存标识符。

        shmaddr:指定共享内存段应连接到的地址,通常设置为NULL,让系统自动选择。

        shmflg:控制共享内存段连接的方式,如SHM_RDONLY表示只读。

        返回值:成功时,返回指向共享内存段的指针。失败时返回(void *) -1,可通过errno获取具体的错误代码。

        3、shmdt:将共享内存段从调用进程的地址空间分离。其函数原型如下。

int shmdt(const void *shmaddr);

        各个参数和返回值的含义如下。

        shmaddr:由shmat返回的地址。

        返回值:成功时,返回0。失败时返回-1,可通过errno获取具体的错误代码。

        4、shmctl:执行多种控制操作,如获取共享内存段的状态、设置共享内存段的状态、删除共享内存段等。其函数原型如下。

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

        各个参数和返回值的含义如下。

        shmid:由shmget函数返回的共享内存标识符。

        cmd:命令ID,比如,IPC_STAT表示获取状态、IPC_SET表示设置状态、IPC_RMID表示移除段。

        buf:根据命令不同,可能需要提供一个指向struct shmid_ds结构体的指针。

        返回值:成功时,返回0。失败时返回-1,可通过errno获取具体的错误代码。

实战代码

        在下面的实战代码中,我们使用共享内存机制来创建、写入和分离一个共享内存段。

        首先,通过调用ftok函数并传入一个路径名和一个项目ID,生成一个唯一的键值,该键值用于后续标识共享内存段。然后,利用shmget函数根据这个键值创建一个新的共享内存段。这里指定共享内存的大小为1024字节,并设置了权限标志,以确保创建时赋予读写权限给所有用户。

        一旦成功获得共享内存段的标识符shmid,我们便通过shmat函数将这个共享内存段连接到当前进程的地址空间中。shmat会返回一个指向共享内存起始位置的指针,随后,我们使用strcpy函数将字符串复制到该指针中。

        最后,我们调用shmdt函数将共享内存段从当前进程的地址空间中进行了分离。

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>int main()
{// 创建唯一的键key_t key = ftok("shmfile", 66);// 创建共享内存段int shmid = shmget(key, 1024, 0666|IPC_CREAT);// 连接共享内存段char *pszBuffer = (char*)shmat(shmid, (void*)0, 0);strcpy(pszBuffer, "Hello, Hope_Wisdom");printf("Data written in memory: %s\n", pszBuffer);// 分离共享内存段shmdt(pszBuffer);return 0;
}

        为了与上面的进程相配合,我们实现了下面的进程,使用共享内存机制来获取、读取和管理一个共享内存段。

        首先,我们调用shmget函数根据键值获取一个已经存在的共享内存段。这里指定共享内存的大小为1024字节,并设置了权限标志,以确保创建时赋予读写权限给所有用户。

        一旦成功获得共享内存段的标识符shmid,我们便通过shmat函数将这个共享内存段连接到当前进程的地址空间中。shmat会返回一个指向共享内存起始位置的指针,随后,我们直接尝试从该指针读取数据并打印出来。

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>int main()
{// 创建唯一的键key_t key = ftok("shmfile", 66);// 获取共享内存段IDint shmid = shmget(key, 1024, 0666|IPC_CREAT);// 连接共享内存段char *pszBuffer = (char*)shmat(shmid, (void*)0, 0);printf("Data read from memory: %s\n", pszBuffer);// 分离共享内存段shmdt(pszBuffer);// 删除共享内存段shmctl(shmid, IPC_RMID, NULL);return 0;
}

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

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

相关文章

零知开源——STM32F407VET6驱动Flappy Bird游戏教程

简介 本教程使用STM32F407VET6零知增强板驱动3.5寸TFT触摸屏实现经典Flappy Bird游戏。通过触摸屏控制小鸟跳跃&#xff0c;躲避障碍物柱体&#xff0c;挑战最高分。项目涉及STM32底层驱动、图形库移植、触摸控制和游戏逻辑设计。 目录 简介 一、硬件准备 二、软件架构 三、…

Elasticsearch创建快照仓库报错处理

创建快照仓库报错&#xff1a; 根据报错提示的信息&#xff0c;问题可能出在 Elasticsearch 的配置中。当你尝试创建一个文件系统&#xff08;fs&#xff09;类型的快照仓库时&#xff0c;虽然已经指定了 location 参数&#xff0c;但 Elasticsearch 仍然报错&#xff0c;这通…

服务器如何配置防火墙管理端口访问?

配置服务器防火墙来管理端口访问&#xff0c;是保障云服务器安全的核心步骤。下面我将根据你使用的不同操作系统&#xff08;Linux: Ubuntu/Debian/CentOS&#xff1b;Windows Server&#xff09;介绍常用防火墙配置方法。 ✅ 一、Linux 防火墙配置&#xff08;UFW / firewalld…

Redis最佳实践——安全与稳定性保障之连接池管理详解

Redis 在电商应用的连接池管理全面详解 一、连接池核心原理与架构 1. 连接池工作模型 #mermaid-svg-G7I3ukCljlJZAXaA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-G7I3ukCljlJZAXaA .error-icon{fill:#552222;}…

打印机无法远程打印?可以本地打印,本地网络打印机设置给异地使用

很多小伙伴常有打印、远程打印的需求&#xff0c;特别是对于电商人、跨境电商、教师、产品经理、实验人员等群体来说掌握这项技能可谓是能够在很多场景下带来便捷&#xff0c;大幅提升做事效率&#xff01;打印机是家庭和企业经常用到的设备&#xff0c;很多情况下会遇到本地可…

【Linux】进程地址空间揭秘(初步认识)

10.进程地址空间&#xff08;初步认识&#xff09; 文章目录 10.进程地址空间&#xff08;初步认识&#xff09;一、进程地址空间的实验现象解析二、进程地址空间三、虚拟内存管理补充&#xff1a;数据的写时拷贝&#xff08;浅谈&#xff09;补充&#xff1a;页表&#xff08;…

深入探讨redis:主从复制

前言 如果某个服务器程序&#xff0c;只部署在一个物理服务器上就可能会面临一下问题(单点问题) 可用性问题&#xff0c;如果这个机器挂了&#xff0c;那么对应的客户端服务也相继断开性能/支持的并发量有限 所以为了解决这些问题&#xff0c;就要引入分布式系统&#xff0c…

MacOS安装Docker Desktop并汉化

1. 安装Docker Desktop 到Docker Desktop For Mac下载对应系统的Docker Desktop 安装包&#xff0c;下载后安装&#xff0c;没有账号需要注册&#xff0c;然后登陆即可。 2. 汉化 前往汉化包下载链接下载对应系统的.asar文件 然后将安装好的文件覆盖原先的文件app.asar文件…

索引的选择与Change Buffer

1. 索引选择与Change Buffer 问题引出&#xff1a;普通索引 vs 唯一索引 ——如何选择&#xff1f; 在实际业务中&#xff0c;如果一个字段的值天然具有唯一性&#xff08;如身份证号&#xff09;&#xff0c;并且业务代码已确保无重复写入&#xff0c;那就存在两种选择&…

lua注意事项

感觉是lua的一大坑啊&#xff0c;它还不如函数内部就局部变量呢 注意函数等内部&#xff0c;全部给加上local得了

【多线程初阶】死锁的产生 如何避免死锁

文章目录 关于死锁一.死锁的三种情况1.一个线程,一把锁,连续多次加锁2.两个线程,两把锁3.N个线程,M把锁 --哲学家就餐问题 二.如何避免死锁死锁是如何构成的(四个必要条件)打破死锁 三.死锁小结 关于死锁 一.死锁的三种情况 1.一个线程,一把锁,连续多次加锁 -->由synchroni…

【NLP基础知识系列课程-Tokenizer的前世今生第二课】NLP 中的 Tokenizer 技术发展史

从词表到子词&#xff1a;Tokenizer 的“进化树” 我们常说“语言模型是理解人类语言的工具”&#xff0c;但事实上&#xff0c;模型能不能“理解”&#xff0c;关键要看它接收到了什么样的输入。而 Tokenizer&#xff0c;就是这一输入阶段的设计者。 在 NLP 的发展历程中&am…

Rust 学习笔记:循环和迭代器的性能比较

Rust 学习笔记&#xff1a;循环和迭代器的性能比较 Rust 学习笔记&#xff1a;循环和迭代器的性能比较示例 1示例 2总结 Rust 学习笔记&#xff1a;循环和迭代器的性能比较 示例 1 我们运行一个基准测试&#xff0c;将《福尔摩斯探案集》的全部内容加载到一个字符串中&#x…

pod创建和控制

一、引言 ‌主题‌&#xff1a;pod以及控制器模式中的Deployment作用。‌控制器模式&#xff1a;使用一种API对象&#xff08;如Deployment&#xff09;管理另一种API对象&#xff08;如Pod&#xff09;的方式。 二、容器镜像与配置文件 ‌容器镜像‌&#xff1a;应用开发者…

HTML实战:爱心图的实现

设计思路 使用纯CSS创建多种风格的爱心 添加平滑的动画效果 实现交互式爱心生成器 响应式设计适应不同设备 优雅的UI布局和色彩方案 <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <meta nam…

2022年 中国商务年鉴(excel电子表格版)

2022年 中国商务年鉴&#xff08;excel电子表格版&#xff09;.ziphttps://download.csdn.net/download/2401_84585615/89772883 https://download.csdn.net/download/2401_84585615/89772883 《中国商务年鉴2022》是由商务部国际贸易经济合作研究院主办的年度统计资料&#xf…

Redis核心数据结构操作指南:字符串、哈希、列表详解

注&#xff1a;此为苍穹外卖学习笔记 Redis作为高性能的键值数据库&#xff0c;其核心价值来自于丰富的数据结构支持。本文将深入解析字符串&#xff08;String&#xff09;、哈希&#xff08;Hash&#xff09;、**列表&#xff08;List&#xff09;**三大基础结构的操作命令&…

如何以 9 种方式将照片从 iPhone 传输到笔记本电脑

您的 iPhone 可能充满了以照片和视频形式捕捉的珍贵回忆。无论您是想备份它们、在更大的屏幕上编辑它们&#xff0c;还是只是释放设备上的空间&#xff0c;您都需要将照片从 iPhone 传输到笔记本电脑。幸运的是&#xff0c;有 9 种方便的方法可供使用&#xff0c;同时满足 Wind…

如何使用Python从MySQL数据库导出表结构到Word文档

在开发和维护数据库的过程中&#xff0c;能够快速且准确地获取表结构信息是至关重要的。本文将向您展示一种简单而有效的方法&#xff0c;利用Python脚本从MySQL数据库中提取指定表的结构信息&#xff0c;并将其导出为格式化的Word文档。此方法不仅提高了工作效率&#xff0c;还…

写作-- 复合句练习

文章目录 练习 11. 家庭的支持和老师的指导对学生的学术成功有积极影响。2. 缺乏准备和未能适应通常会导致在挑战性情境中的糟糕表现。3. 吃垃圾食品和忽视锻炼可能导致严重的健康问题,因此人们应注重保持均衡的生活方式。4. 昨天的大雨导致街道洪水泛滥,因此居民们迁往高地以…