当前位置: 首页 > news >正文

手机站建设o2o商城网站系统开发

手机站建设,o2o商城网站系统开发,无忧代理 在线,关于普通话的手抄报目录 1. 共享内存 1.1基本概念 1.2核心特点 2.共享内存操作 2.1 获得一个共享存储标识符shmget 应用场景 2.2 共享内存映射(shmat) 2.3 解除共享内存映射(shmdt) 2.4 共享内存控制shmctl 2.4.1 删除共享内存标识符 2.4.2 修改权限 2.5共享内存大小修改 2.5.1标准方…

目录

1. 共享内存

1.1基本概念

1.2核心特点

2.共享内存操作

2.1 获得一个共享存储标识符shmget

应用场景

2.2 共享内存映射(shmat)

2.3 解除共享内存映射(shmdt)

2.4 共享内存控制shmctl

2.4.1 删除共享内存标识符

2.4.2 修改权限

2.5共享内存大小修改

2.5.1标准方法1-删除旧空间开辟新空间

2.5.2标准方法2-删除旧空间开辟新空间,并写入数据


1. 共享内存

1.1基本概念

共享内存(Shared Memory)‌ 是 Linux 系统中进程间通信(IPC)的一种高效方式,允许多个进程通过访问同一块物理内存区域实现数据共享,无需内核中转数据。

共享内存是进程间通信方式中效率最高 的,原因在于进程是直接在物理内存上进行操 作,将物理地址映射到用户进程这,所以只要对其地址进行操作,就是直接对物理地址操作。
  • 核心机制‌:操作系统分配共享内存后,各进程将其映射到自身虚拟地址空间,直接读写同一物理内存区域
  • 优势‌:数据无需复制,通信速度极快,适合大规模或高频数据交换。
  • 局限性‌:需手动实现同步机制(如信号量)以避免数据竞争。

使用 shell 命令操作共享内存:
ipcs -m //查看共享内存
ipcrm -m shmid //删除共享内存

1.2核心特点

‌1.高效性

直接操作内存,避免内核介入和数据复制,性能显著优于管道、消息队列等。

2‌.全局性

所有关联进程均可访问同一内存区域,实现数据全局共享。

‌3.同步依赖

需结合信号量、互斥锁等机制保证数据一致性

2.共享内存操作

2.1 获得一个共享存储标识符shmget

应用场景
  1. 创建新共享内存段

    int shmid = shmget(ftok("/tmp", 100), 1024, IPC_CREAT | 0666);通过 ftok 生成 key,并指定权限为所有用户可读写。

    ftok函数函数原型:详细链接https://blog.csdn.net/weixin_45842280/article/details/136384000

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id); 参数:
pathname 参数是一个指向字符串的指针,用于指定一个已经存在的文件的路径名。proj_id 参数是一个用户定义的整数,可以是 0 到 255 的范围内的任意值。  ftok 函数会根据指定的 pathname 和 proj_id 生成一个唯一的键值,
用于创建或访问 System V IPC 的资源,如共享内存、信号量和消息队列。  实际上,ftok 函数根据 pathname 参数对应文件的 inode 号和 proj_id 
参数生成一个 32 位的键值,最高 8 位存放 proj_id,低 24 位存放 pathname 
对应文件的 inode 号的后 24 位。这样可以保证相同的 pathname 和 proj_id 
参数生成相同的键值。   需要注意的是,在使用 ftok 函数时要确保 pathname 
参数是一个已经存在的文件的路径名,否则会导致生成的键值不唯一。另外,
proj_id 参数的取值范围是 0 到 255,超出这个范围可能导致键值重复。 综上所述,ftok 函数是用于生成 System V IPC 键值的一个实用工具函数,
可以通过指定文件路径和项目标识来确保生成唯一的键值,用于进程间通信的各种资源的创建和访问。

2‌.获取已有内存段

int shmid = shmget(existing_key, 0, 0); // 无需指定 size 和权限

3‌.强制创建新内存段

int shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT | IPC_EXCL | 0600);使用 IPC_PRIVATE 确保唯一性,防止其他进程获取

shmget函数原型:

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size,int shmflg);功能:
创建或打开一块共享内存区参数:
key:IPC 键值
size:该共享存储段的长度(字节)
shmflg:标识函数的行为及共享内存的权限。IPC_CREAT:如果不存在就创建IPC_EXCL:如果已经存在则返回失败位或权限位:共享内存位或权限位后可以设置共享内存的访问权限,格式和 open 函数的 mode_t 一样,但可执行权限未使用。返回值:
成功:返回共享内存标识符。
失败:返回-1。

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main(int argc, char const *argv[])
{//使用ftok函数获取键值key_t mykey;if((mykey = ftok(".", 100)) == -1){perror("fail to ftok");exit(1);}//通过shmget函数创建或者打开一个共享内存,返回一个共享内存的标识符int shmid;//创建一个共享内存,500字节,不存在创建,权限:可读可写if((shmid = shmget(mykey, 500, IPC_CREAT | 0666)) == -1){perror("fail to shmget");exit(1);}printf("shmid = %d\n", shmid);system("ipcs -m");//执行ipcs -m 命令return 0;
}

运行结果:

由于共享内存段过多,使用grep命令进行过滤。

2.2 共享内存映射(shmat)

函数原型:

#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);功能:
将一个共享内存段映射到调用进程的数据段中。参数:
shmid:共享内存标识符。
shmaddr:共享内存映射地址(若为 NULL 则由系统自动指定),推荐使用 NULL。
shmflg:共享内存段的访问权限和映射条件0:共享内存具有可读可写权限。SHM_RDONLY:只读。SHM_RND:(shmaddr 非空时才有效)
没有指定 SHM_RND 则此段连接到 shmaddr 所指定的地址上(shmaddr 必需页对齐)。
指定了 SHM_RND 则此段连接到 shmaddr- shmaddr%SHMLBA 所表示的地址上。返回值:
成功:返回共享内存段映射地址
失败:返回 (void *)-1

2.3 解除共享内存映射(shmdt)

函数原型:

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

程序:

(1)写入数据

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>typedef struct
{int a;char b;
}MSG;int main(int argc, char const *argv[])
{//使用ftok函数获取键值key_t mykey;if((mykey = ftok(".", 100)) == -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");//执行ipcs -m 命令,查看共享内存//使用shmat函数映射共享内存的地址//char *text;MSG *text;if((text = shmat(shmid, NULL, 0)) == (void *)-1){perror("fail to shmat");exit(1);}//通过shmat的返回值对共享内存操作//strcpy(text, "hello world");text->a = 100;text->b = 'w';//操作完毕后要解除共享内存的映射if(shmdt(text) == -1){perror("fail to shmdt");exit(1);}system("ipcs -m");return 0;
}

(2)读取数据

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>typedef struct
{int a;char b;
}MSG;int main(int argc, char const *argv[])
{//使用ftok函数获取键值key_t mykey;if((mykey = ftok(".", 100)) == -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);}system("ipcs -m");//执行ipcs -m 命令,查看共享内存//映射共享内存的地址//char *text;MSG *text;if((text = shmat(shmid, NULL, 0)) == (void *)-1){perror("fail to shmat");exit(1);}//获取共享内存中的数据//printf("text = %s\n", text);printf("a = %d, b = %c\n", text->a, text->b);//解除共享内存映射if(shmdt(text) == -1){perror("fail to shmdt");exit(1);}system("ipcs -m");return 0;
}

运行结果:

(1)写入数据

(2)读取数据

2.4 共享内存控制shmctl

函数原型:

shmid_ds结构体结构体详细链接:https://zhuanlan.zhihu.com/p/91033039

#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);功能:
共享内存空间的控制。参数:
shmid:共享内存标识符。
cmd:函数功能的控制。IPC_RMID:删除。IPC_SET:设置 shmid_ds 参数。IPC_STAT:保存 shmid_ds 参数。SHM_LOCK:锁定共享内存段(超级用户)。SHM_UNLOCK:解锁共享内存段。
buf:shmid_ds 数据类型的地址,用来存放或修改共享内存的属性。返回值:
成功返回 0,失败返回 -1。shmid_ds结构体:
struct shmid_ds 
{// 权限相关struct ipc_perm shm_perm;	/* operation perms */// 共享内存的大小int	shm_segsz;		/* size of segment (bytes) */time_t	shm_atime;		/* last attach time */time_t	shm_dtime;		/* last detach time */time_t	shm_ctime;		/* last change time */// 创建该结构体的进程unsigned short	shm_cpid;	/* pid of creator */unsigned short	shm_lpid;	/* pid of last operator */// 当前使用该共享内存的进程数short	shm_nattch;		/* no. of current attaches *//* the following are private */// 共享内存的页数unsigned short   shm_npages;	/* size of segment (pages) */// 指向共享的物理内存的指针unsigned long   *shm_pages;	/* array of ptrs to frames -> SHMMAX */ // 使用该共享内存的进程信息struct vm_area_struct *attaches; /* descriptors for attaches */
}

2.4.1 删除共享内存标识符

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main(int argc, char const *argv[])
{//使用ftok函数获取键值key_t mykey;if((mykey = ftok(".", 100)) == -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");//执行ipcs -m 命令,查看共享内存//通过shmctl函数删除共享内存if(shmctl(shmid, IPC_RMID, NULL) == -1){perror("fail to shmctl");exit(1);}system("ipcs -m");return 0;
}

运行结果:

(1)第一次 ipcs -m 命令

(2)第二次 ipcs -m 命令

终端执行 ipcs -m | grep 98355 命令,无输出,已删除。

2.4.2 修改权限

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main(int argc, char const *argv[])
{//使用ftok函数获取键值key_t mykey;if((mykey = ftok(".", 100)) == -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");//执行ipcs -m 命令,查看共享内存struct shmid_ds info;int ctl = shmctl(shmid, IPC_STAT, &info);  // 获取当前状态信息if(ctl == -1){perror("fail to shmctl");exit(1);}printf("权限 = %o\n", info.shm_perm.mode);info.shm_perm.mode = 0644;  // 修改权限ctl = shmctl(shmid, IPC_SET, &info);// 提交修改if(ctl == -1){perror("fail to shmctl");exit(1);}printf("提交修改后 权限 = %o\n", info.shm_perm.mode);// 验证修改是否生效struct shmid_ds new_info;ctl = shmctl(shmid, IPC_STAT, &new_info);if(ctl == -1){perror("fail to shmctl");exit(1);}printf("新修改  权限 = %o\n" new_info.shm_perm.mode);system("ipcs -m");//执行ipcs -m 命令,查看共享内存//通过shmctl函数删除共享内存if(shmctl(shmid, IPC_RMID, NULL) == -1){perror("fail to shmctl");exit(1);}return 0;
}

运行结果:

2.5共享内存大小修改

2.5.1标准方法1-删除旧空间开辟新空间

程序:

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>//场景一:标准方法(删除旧内存段 + 重新创建)
int main() 
{// 1. 创建初始共享内存(100字节)int shmid = shmget(IPC_PRIVATE, 100, 0666 | IPC_CREAT);if (shmid == -1) {perror("shmget failed");return -1;}struct shmid_ds info;int ctl = shmctl(shmid, IPC_STAT, &info);  // 获取当前状态信息if(ctl == -1){perror("fail to shmctl");exit(1);}printf("空间大小 = %d\n", info.shm_segsz);// 2. 删除旧内存段(需确保无进程附加)if (shmctl(shmid, IPC_RMID, NULL) == -1){perror("shmctl IPC_RMID failed");return -1;}// 3. 创建新内存段(200字节)int new_shmid = shmget(IPC_PRIVATE, 200, 0666 | IPC_CREAT);if (new_shmid == -1) {perror("shmget for new size failed");return -1;}ctl = shmctl(new_shmid, IPC_STAT, &info);  // 获取当前状态信息if(ctl == -1){perror("fail to shmctl");exit(1);}printf("新 空间大小 = %d\n", info.shm_segsz);// 4. 清理资源shmctl(new_shmid, IPC_RMID, NULL);  // 标记删除新内存段return 0;
}

运行结果:

2.5.2标准方法2-删除旧空间开辟新空间,并写入数据

程序:

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>//场景一:标准方法(删除旧内存段 + 重新创建)
int main() 
{// 1. 创建初始共享内存(100字节)int shmid = shmget(IPC_PRIVATE, 100, 0666 | IPC_CREAT);if (shmid == -1) {perror("shmget failed");return -1;}// 2. 写入初始数据char *data = shmat(shmid, NULL, 0);strcpy(data, "Hello, World!");printf("旧空间数据: %s\n", data);struct shmid_ds info;int ctl = shmctl(shmid, IPC_STAT, &info);  // 获取当前状态信息if(ctl == -1){perror("fail to shmctl");exit(1);}printf("空间大小 = %d\n", info.shm_segsz);// 3. 删除旧内存段(需确保无进程附加)if (shmctl(shmid, IPC_RMID, NULL) == -1){perror("shmctl IPC_RMID failed");return -1;}// 4. 创建新内存段(200字节)int new_shmid = shmget(IPC_PRIVATE, 200, 0666 | IPC_CREAT);if (new_shmid == -1) {perror("shmget for new size failed");return -1;}ctl = shmctl(new_shmid, IPC_STAT, &info);  // 获取当前状态信息if(ctl == -1){perror("fail to shmctl");exit(1);}printf("新 空间大小 = %d\n", info.shm_segsz);// 5. 迁移数据到新内存段char *new_data = shmat(new_shmid, NULL, 0);//映射内存strcpy(new_data, data);printf("新空间数据: %s\n", new_data);// 6. 清理资源shmdt(data);//结束映射shmdt(new_data);shmctl(new_shmid, IPC_RMID, NULL);  // 标记删除新内存段return 0;
}

运行结果:

http://www.dtcms.com/a/471122.html

相关文章:

  • 国产三维CAD皇冠CAD(CrownCAD)在「汽车零部件」建模教程:发动机零件
  • 中国网站的建设无锡企业做网站
  • systemd-journald和rsyslogd日志配置详解
  • figma打开编辑器时发生错误
  • 网站备案有效期知乎问答网站开发教程
  • ArkTS 与 TypeScript:鸿蒙生态下的语言演进与实践指南
  • AI 赋能 IBMS 集成系统:从 “数据集成中枢” 到 “智慧决策大脑” 的跃升
  • 做医疗网站颜色选择杭州网页设计招聘网
  • 力扣面试经典150题day3第五题(lc69),第六题(lc189)
  • 做网站去哪好盘锦威旺做网站建设
  • 字符串相关的方法有哪些?
  • 标签预制体上的组件
  • cms免费企业网站湖南网站模板建站
  • 【流氓软件】流氓软件及处理方法
  • 网站开发职业怎么经营网店生意才会好
  • 自动化脚本矩阵运营
  • 《Effective Java》第一条:用静态工厂方法代替构造器
  • 怎么做可以访问网站连接加密互联网营销模式
  • Diff-Shadow阴影去除
  • 怎么去接网站来做天津手机网站建设制作
  • 引擎搜索入口aso优化重要吗
  • 做外贸 需要做网站吗知名网站定制报价
  • 四川刚刚发布的最新新闻seo标题优化
  • 一文读懂 Flink Exactly-Once 保证机制深度解析
  • wordpress批量发布内容好的seo平台
  • Unity框架YouYouFramework学习第1篇:游戏入口
  • 专业的建设网站服务公司.网站建设课程设计
  • lnmp利用wordpress网站内链优化策略
  • 宁波做网站的哪个好logo设计多少钱
  • 昂瑞微:科创板逐浪者,射频“芯”征程的领航旗舰