首页 > 系统相关 >2024-02-27-物联网系统编程(7- 共享内存)

2024-02-27-物联网系统编程(7- 共享内存)

时间:2024-02-27 14:33:30浏览次数:33  
标签:02 0x00000000 27 spider 2024 include 524288 shmid 共享内存

7. 共享内存

7.1 共享内存概述

​ 共享内存允许两个或者多个进程共享给定的区域

共享内存的特点

  1. 共享内存是进程间共享数据的一种最快的方法;
    一个进程向共享的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容
  2. 使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥
    若一个进程正在向共享内存区写数据,则在它做完这一步操作前,别的进程不应当去读、写这些数据。
image-20240227110117801

7.2 共享内存的操作

7.2.1 获得一个共享内存标识符 - shmget

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key,size_t size, int shmflg);
功能: 创建一个共享内存
参数:
	key:键值,唯一的键值确定唯一的共享内存size:创建的共享内存的大小
	shmflg:共享内存的访问权限, 一般为 IPC_CREAT|0777
返回值:
	成功: 共享内存的id
	失败: -1

使用shell命令操作共享内存

# 查看共享内存
ipcs -m
    
# 删除共享内存
ipcrm -m shmid
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    // 使用ftok函数获取键值
    key_t mykey;
    if ((mykey = ftok(".", 15)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }

    // 通过shmget函数创建后者打开一个共享内存,返回一个共享内存标识符
    int shmid;
    if ((shmid = shmget(mykey, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }
    printf("shmid = %d\n", shmid);
    system("ipcs -m");

    return 0;
}

输出结果

image-20240227111656631

7.2.2 共享内存映射- attach

#include<sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr,,int shmflg)
功能: 映射共享内存;
参数:
	shmid: 共享内存标识符id 
	shmaddr: 共享内存映射地址(若为NULL 则由系统自动指定),推荐使用 NULL;
	shmflg: 标志位
		0: 共享内存具有可读可写权限。
        SHM_RDONLY: 只读。
返回值:
    成功: 返回共享内存段映射地址
    失败: 返回 -1

注意:shmat函数使用的时候第二个和第三个参数一般设为NULL0,即系统自动指定共享内存地址,并且共享内存可读可写。

7.2.3 解除内存映射 - detach

#include<sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr)
功能:将共享内存和当前进程分离(仅仅是断开联系并不删除共享内存);
参数: shmaddr 映射的地址,即shmat的返回值;
返回值:
    成功:0;
    失败:-1

7.2.4 读写案例

shmat_write.c

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

int main(int argc, char const *argv[])
{
    // 使用ftok函数获取键值
    key_t mykey;
    if ((mykey = ftok(".", 15)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }

    // 通过shmget函数创建后者打开一个共享内存,返回一个共享内存标识符
    int shmid;
    if ((shmid = shmget(mykey, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }
    printf("shmid = %d\n", shmid);
    system("ipcs -m");

    // 使用shmat函数映射共享内存的地址
    char *text;
    if ((text = shmat(shmid, NULL, 0)) == (void *)-1)
    {
        perror("fail to shmat");
        exit(1);
    }
    strcpy(text, "hello world");
    // 解除共享内存映射
    if (shmdt(text) == -1)
    {
        perror("fail to shmdt");
        exit(1);
    }
    system("ipcs -m");
}

输出结果

shmid = 32810

------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态      
0x00000000 13         spider     600        524288     2          目标       
0x00000000 16         spider     600        524288     2          目标       
0x00000000 18         spider     600        524288     2          目标       
0x00000000 19         spider     606        9126624    2          目标       
0x00000000 20         spider     606        9126624    2          目标       
0x00000000 32803      spider     600        524288     2          目标       
0x0f0516f4 32810      spider     666        500        0                       


------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态      
0x00000000 13         spider     600        524288     2          目标       
0x00000000 16         spider     600        524288     2          目标       
0x00000000 18         spider     600        524288     2          目标       
0x00000000 19         spider     606        9126624    2          目标       
0x00000000 20         spider     606        9126624    2          目标       
0x00000000 32803      spider     600        524288     2          目标       
0x0f0516f4 32810      spider     666        500        0      

shmat_read.c

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

int main(int argc, char const *argv[])
{
    // 使用ftok函数获取键值
    key_t mykey;
    if ((mykey = ftok(".", 15)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }

    // 通过shmget函数创建后者打开一个共享内存,返回一个共享内存标识符
    int shmid;
    if ((shmid = shmget(mykey, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }
    printf("shmid = %d\n", shmid);
    system("ipcs -m");

    // 使用shmat函数映射共享内存的地址
    char *text;
    if ((text = shmat(shmid, NULL, 0)) == (void *)-1)
    {
        perror("fail to shmat");
        exit(1);
    }
    // 获取共享内存中的数据
    printf("text = %s\n", text);
    // 解除共享内存映射
    if (shmdt(text) == -1)
    {
        perror("fail to shmdt");
        exit(1);
    }
    system("ipcs -m");
}

输出结果

shmid = 32810

------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态      
0x00000000 13         spider     600        524288     2          目标       
0x00000000 16         spider     600        524288     2          目标       
0x00000000 18         spider     600        524288     2          目标       
0x00000000 19         spider     606        9126624    2          目标       
0x00000000 20         spider     606        9126624    2          目标       
0x00000000 32803      spider     600        524288     2          目标       
0x0f0516f4 32810      spider     666        500        0                       

text = hello world

------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态      
0x00000000 13         spider     600        524288     2          目标       
0x00000000 16         spider     600        524288     2          目标       
0x00000000 18         spider     600        524288     2          目标       
0x00000000 19         spider     606        9126624    2          目标       
0x00000000 20         spider     606        9126624    2          目标       
0x00000000 32803      spider     600        524288     2          目标       
0x0f0516f4 32810      spider     666        500        0           

7.3 共享内存的控制

#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid int cmd, struct shmid_ds *buf)
功能:	设置或者获取共享内存你的属性;
参数:
	shmid:	共享内存的id;
	cmd:执行操作的命令
		IPC_STAT 获取共享内存的属性
		IPC_SET 设置共享内存的属性
         IPC_RMID 删除共享内存
    shmid_ds:共享内存的属性结构体;
返回值:
	成功:0
	失败:-1
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    // 使用ftok函数获取键值
    key_t mykey;
    if ((mykey = ftok(".", 15)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }

    // 通过shmget函数创建后者打开一个共享内存,返回一个共享内存标识符
    int shmid;
    if ((shmid = shmget(mykey, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }
    printf("shmid = %d\n", shmid);
    system("ipcs -m");
    // t通过shmctl函数删除共享内存
    if (shmctl(shmid, IPC_RMID, NULL) == -1)
    {
        perror("fail to shmctl");
        exit(1);
    }
    system("ipcs -m");

    return 0;
}
shmid = 32810

------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态      
0x00000000 13         spider     600        524288     2          目标       
0x00000000 16         spider     600        524288     2          目标       
0x00000000 18         spider     600        524288     2          目标       
0x00000000 19         spider     606        9126624    2          目标       
0x00000000 20         spider     606        9126624    2          目标       
0x00000000 32803      spider     600        524288     2          目标       
0x0f0516f4 32810      spider     666        500        0                       


------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态      
0x00000000 13         spider     600        524288     2          目标       
0x00000000 16         spider     600        524288     2          目标       
0x00000000 18         spider     600        524288     2          目标       
0x00000000 19         spider     606        9126624    2          目标       
0x00000000 20         spider     606        9126624    2          目标       
0x00000000 32803      spider     600        524288     2          目标    

标签:02,0x00000000,27,spider,2024,include,524288,shmid,共享内存
From: https://www.cnblogs.com/hasaki-yasuo/p/18036809

相关文章

  • 20240219
    State的使用在Compose中,我们可以使用State来管理数据,State是一个可以被观察的数据,当数据发生变化时,State会通知所有的观察者。我们可以使用State来管理UI的状态,比如显示和隐藏组件、改变组件的样式等。什么时候使用State当我们需要管理UI的状态时,我们可以使用State。比如,当我们......
  • 20240218
    记账本App主页页面的绘制记账本App的主页界面绘制@OptIn(ExperimentalMaterial3Api::class)@ComposablefunExpenseTrackerApp(appViewModel:ExpenseTrackerViewModel=viewModel()){valappUiStatebyappViewModel.uiState.collectAsState()Box(modifie......
  • 【2024-02-18】连岳摘抄
    23:59在即将远行和改变生活方式的时刻,善于反省的人总怀着一种严肃的心情。每逢这样的时刻,人们通常是检查过去和计划未来。                                                ......
  • 【2024-02-17】连岳摘抄
    23:59尽管如此,还要坚持,希望就像盐巴一样,没有营养,但它给面包增添了味道。                                                 ——若泽·萨拉马戈强者可以制定规则,强者......
  • 2024-02-27-物联网系统编程(6-消息队列)
    6.消息队列6.1IPC对象​除了最原始的进程间通信方式信号、无名管道和有名管道外,还有三种进程间通信方式,这三种方式称之为IPC对象:消息队列、共享内存、信号灯集。​IPC对象也是在内核空间开辟区域,每一种IPC对象创建好之后都会将其设置为全局,并且会给其分配一......
  • 2.27每日总结
    今天课上学习了软件测试技术,对软件测试技术有了简单的了解。软件测试技术是一门涉及软件质量保证和验证的课程,旨在教授学生如何设计、执行和评估软件测试方案以确保软件系统的质量。这门课程通常涵盖以下内容:软件测试基础知识:介绍软件测试的基本概念、原则和方法论,包括白盒测......
  • 2024 省选复习 (updating)
    前言快省选了,在复习,但是不知道干什么。所以就写点东西吧。就是瞎写写,所以可能有很多错误,如果发现了欢迎指出。常见错误&注意事项数组不能开大,也不能开小题目要求什么千万不能读错,最好手算一下样例算法复习树状数组进阶P6619原本是树状数组二分的模板题,但是用......
  • 2023 csp游记
    省流:XJ小丑,挂分笑话初赛前一天晚上2023年9月15日学了一会数学,学傻了,还是题题不会,希望明天初赛能有个好成绩。看到了一些与我年龄相同但爆杀我的人,觉得自己太菜了。初赛当天2023年9月16日早上6:30起来了,觉得稍微有点困,稍微复习了一会,吃了个早饭就出发去海创了。海创很大,门......
  • 蒟蒻的2023NOIP游记(非正式)
    前言:这是篇blog这周集中打模拟赛的记录,后会和NOIP场外游记并在一起。11/11双十一,打了两场共同体NOIP模拟赛157:55左右开题t1,t2,t3,t4看了一眼,觉得t1,t2可做想t1,到8:40想出了做法(赛后看来离正解挺近的),9:30左右写好。对于一张n个点的图,由菊花图可想到,应该是对半开。......
  • 20240226
    非常意识流的日记,精神状态极度不佳下打出来的。模拟赛垫底,不过是意料之中的,没造成太大影响。下午也很正常,一直在硬刚Border,不过有些微疲倦。晚自习就开始颓废了,不想学习。然后下去散步的时候唐了,成小丑了,破防了。当时看到青蛙的博客时真正体会到了什么是「整个人都麻了」的......