查看“C++ Linux共享内存”的源代码
←
C++ Linux共享内存
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
==概念与原理== 共享内存是一种高效的进程间通信机制,允许多个进程直接访问同一块物理内存。共享内存是所有IPC机制中最快的,因为数据不需要在内核和用户空间之间进行复制。 ==核心点== * 创建共享内存:使用shmget系统调用创建。 * 附加共享内存:使用shmat系统调用将共享内存附加到进程地址空间。 * 分离共享内存:使用shmdt系统调用分离共享内存。 * 删除共享内存:使用shmctl系统调用删除共享内存。 ==实现实例== <pre> #include <iostream> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/wait.h> #include <cstring> #include <unistd.h> #define SHM_SIZE 1024 // 共享内存大小 int main() { key_t key = ftok("shmfile", 65); // 生成唯一键 int shmid = shmget(key, SHM_SIZE, 0666|IPC_CREAT); // 创建共享内存段 char *str = (char*) shmat(shmid, nullptr, 0); // 附加到共享内存 pid_t cpid = fork(); if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (cpid == 0) { // 子进程 sleep(1); // 确保父进程先写入 std::cout << "子进程从共享内存读取数据:\n"; std::cout << str << std::endl; shmdt(str); // 分离共享内存 _exit(EXIT_SUCCESS); } else { // 父进程 std::cout << "父进程写入共享内存:\n"; const char* msg = "来自父进程的消息"; strncpy(str, msg, SHM_SIZE); wait(NULL); // 等待子进程 shmdt(str); // 分离共享内存 shmctl(shmid, IPC_RMID, nullptr); // 删除共享内存 exit(EXIT_SUCCESS); } } </pre> ===解析:=== ftok("shmfile", 65):生成一个唯一键。 shmget(key, SHM_SIZE, 0666 | IPC_CREAT):创建共享内存段。 shmat(shmid, NULL, 0):将共享内存段附加到进程地址空间。 子进程:等待父进程将数据写入共享内存,从共享内存读取数据并显示。 父进程:将数据写入共享内存,等待子进程结束,分离并删除共享内存段。 ===运行结果:=== <pre> 父进程写入共享内存: 子进程从共享内存读取数据: 来自父进程的消息 </pre> ==实现实例2== ===共享内存写入端=== <pre> #include <iostream> #include<unistd.h>//unix stand lib #include<sys/types.h> #include<sys/fcntl.h> #include<sys/stat.h> #include<stdio.h> #include<fcntl.h> #include<string.h> #include<dirent.h>//file dir #include <sys/wait.h>//wait func #include <stdlib.h>//ststem #include <signal.h> #include <string.h> #include <sys/msg.h> #include <sys/ipc.h> #include <sys/shm.h> using namespace std; typedef struct { int age; char name[10]; }STU; #define SHM_ZIZE_MAX 4096 int main(int argc, char *argv[]) { int shm_id; shm_id = shmget((key_t)6677, SHM_ZIZE_MAX, IPC_CREAT | 0666);//666可读可写 if (shm_id == -1) { perror("shm create error"); return -1; } STU stu_info = { 19, "rabbit" }; void *shm_addr = NULL; //shmat的第二个参数shm_addr:把共享内存连接到当前进程去的时候准备放置它的那个地址,为NULL为让系统自动选择 //第三个参数是一组按位OR(或)在一起的标志,0表示可读可写 shm_addr = shmat(shm_id, NULL, 0); //要对内存清空一下 memset(shm_addr, 0, SHM_ZIZE_MAX); //写进内存:memcpy因为映射就看做是自己的内存 memcpy(shm_addr, &stu_info, sizeof(STU));//地址,内容,大小 cout << "memcpy(shm_addr, &stu_info, sizeof(STU))" << endl; while(1){sleep(1);} shmdt(shm_addr);//脱钩函数 return 0; } </pre> ===共享内存读出端=== <pre> #include <iostream> #include<unistd.h>//unix stand lib #include<sys/types.h> #include<sys/fcntl.h> #include<sys/stat.h> #include<stdio.h> #include<fcntl.h> #include<string.h> #include<dirent.h>//file dir #include <sys/wait.h>//wait func #include <stdlib.h>//ststem #include <signal.h> #include <string.h> #include <sys/msg.h> #include <sys/ipc.h> #include <sys/shm.h> typedef struct { int age; char name[10]; }STU; #define SHM_ZIZE_MAX 4096 int main(int argc, char *argv[]) { int shm_id; shm_id = shmget((key_t)6677, SHM_ZIZE_MAX, IPC_CREAT | 0666);//666可读可写 if (shm_id == -1) { perror("shm create error"); return -1; } STU stu_info; STU *recv_stu_info; bzero(&stu_info, sizeof(STU)); void *shm_addr = NULL; //shmat的第二个参数shm_addr:把共享内存连接到当前进程去的时候准备放置它的那个地址,为NULL为让系统自动选择 //第三个参数是一组按位OR(或)在一起的标志,SHM_RDONLY表示只读 shm_addr = shmat(shm_id, NULL, SHM_RDONLY); //法一:从内存中拿出来:memcpy因为映射就看做是自己的内存 //memcpy(&stu_info, shm_addr,sizeof(STU));//地址,内容,大小 //cout << "stu_info.name" << stu_info.name << endl; //法二:也可以直接把共享内存指针强制转换成STU*,这时要shmat的参数3改为0读写 //这里也说明如果有进程把数据写入共享内存,如果没有其他进程去修改或清除 //那么数据永远都在里面,消息队列和共享内存里面的数据生命周期和进程不同(进程消失了数据可以还在) recv_stu_info = (STU*)shm_addr; cout << "stu_info.name" << recv_stu_info->name << endl; shmdt(shm_addr);//脱钩函数 return 0; } </pre>
返回至“
C++ Linux共享内存
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
基础知识
正则表达式
Markdown
分布式
项目管理
系统集成项目管理基础知识
云原生
Docker
云原生安全
云原生词汇表
十二因素应用
Kubernetes
音频处理
音频合成
Edge-tts
CMS系统
Docsify
VuePress
Mediawiki
自动生成
Marp
CI/CD
GitLab
设计
颜色
平面设计
AI
数字人
操作系统
GNU/Linux
数据库
Mysql
工具
链入页面
相关更改
特殊页面
页面信息