新闻详情

新闻详情

首页 / 资讯中心 / 详情

共享内存操作梳理

发布时间:2026/6/23 19:45:58
共享内存操作梳理
bcu_shared.c 共享内存操作梳理仅梳理 SQlite/bcu_shared.c 中 POSIX 共享内存的创建、初始化、互斥锁配置及清理全流程。一、涉及的全部共享内存 APIAPI次数作用shm_open1创建/打开共享内存返回文件描述符ftruncate1设定共享内存大小mmap1将共享内存映射到进程地址空间memcpy1将数据库数据整体复制进共享内存pthread_mutexattr_init1初始化互斥锁属性pthread_mutexattr_setpshared1设置属性为进程间共享pthread_mutex_init1在共享内存中初始化互斥锁pthread_mutexattr_destroy1销毁互斥锁属性munmap1解除内存映射代码存在但不可达shm_unlink1删除共享内存代码存在但不可达二、操作时序shm_open() │ ▼ ftruncate() │ ▼ mmap() │ ▼ memcpy() ← 把从 SQLite 加载的5张表数据整体拷入共享内存 │ ▼ pthread_mutexattr_init() │ ▼ pthread_mutexattr_setpshared() ← 关键设为 PTHREAD_PROCESS_SHARED │ ▼ pthread_mutex_init() │ ▼ while(1) { sleep(1); } ← 常驻保持共享内存存活 ▼ (不可达) munmap() shm_unlink() ← 正常清理逻辑但死循环导致永远走不到三、逐步骤详解1.shm_open— 创建共享内存shm_fdshm_open(/bcu_shared_data,O_CREAT|O_RDWR,0666);参数含义/bcu_shared_data共享内存名称其他进程通过同一个名字 attachO_CREAT | O_RDWR不存在则创建以读写方式打开0666权限位所有用户可读写返回值是文件描述符整数在 Linux 上位于/dev/shm/bcu_shared_data。注意此时共享内存大小为 0还不能用。2.ftruncate— 设定大小ftruncate(shm_fd,sizeof(ShareData));把共享内存撑大到sizeof(ShareData)字节。ShareData结构体包含 6 个 Sheet每个放 50 个PointValuepthread_mutex_t大约 26KB。失败则close(shm_fd)并退出。3.mmap— 映射到进程地址空间g_sharedmmap(NULL,sizeof(ShareData),PROT_READ|PROT_WRITE,MAP_SHARED,shm_fd,0);参数含义NULL内核自动选择映射地址sizeof(ShareData)映射大小PROT_READ | PROT_WRITE可读可写MAP_SHARED关键标志修改对所有进程可见shm_fd文件描述符0偏移量从头开始成功返回指向共享内存的指针g_shared之后可以像普通内存一样读写修改会同步到所有 attach 的进程。4.memcpy— 整体复制数据memcpy(g_shared,temp,sizeof(ShareData));在此之前load_sheet_data()已将 5 张 SQLite 表加载到栈上的临时变量ShareData temp。这一步一次性整体拷贝进共享内存所有后续进程看到的就是这份数据。5. 互斥锁初始化 — 进程间同步pthread_mutexattr_tmutex_attr;pthread_mutexattr_init(mutex_attr);pthread_mutexattr_setpshared(mutex_attr,PTHREAD_PROCESS_SHARED);pthread_mutex_init(g_shared-mutex,mutex_attr);pthread_mutexattr_destroy(mutex_attr);这是一个四步走的标准流程步骤函数说明创建属性对象pthread_mutexattr_init在栈上初始化属性结构体设为进程间共享pthread_mutexattr_setpshared核心不加这个标志锁只在单进程内有效初始化锁pthread_mutex_init在共享内存上创建锁所有进程可用销毁属性pthread_mutexattr_destroy栈上的属性对象用完释放之后其他进程如rtu使用LOCK(gbcu_shared-mutex)/UNLOCK(...)即可跨进程同步。6. 常驻循环while(1){sleep(1);}唯一目的保持进程存活。一旦进程退出共享内存虽然不会立即消失还有进程 attach 的话但创建者退出意味着无人负责清理。7. 清理逻辑不可达munmap(g_shared,sizeof(ShareData));// 解除映射close(shm_fd);// 关闭文件描述符shm_unlink(/bcu_shared_data);// 删除共享内存信号处理已注释signal(SIGINT, ...)被注释掉while(1)死循环使得这段代码永不执行。进程只能被kill强制终止。四、其他进程如何 attachrtu.c等进程通过相同 API 附加同一块共享内存// rtu.c 中对应的操作不在本文件仅做对照shm_fdshm_open(/bcu_shared_data,O_RDWR,0);// 名称必须一致gbcu_sharedmmap(NULL,sizeof(ShareData),PROT_READ|PROT_WRITE,MAP_SHARED,shm_fd,0);// 使用LOCK(gbcu_shared-mutex);get_bcu_shared_point_value(系统状态管理、开关控制,120,val);UNLOCK(gbcu_shared-mutex);名称/bcu_shared_data是连接双方的关键约定。五、总结bcu_shared.c的共享内存操作遵循 POSIX 标准五步走shm_open → ftruncate → mmap → 写入数据 → 初始化进程间锁 → 常驻设计要点一次搬运SQLite → 临时结构体 →memcpy进共享内存之后再也不碰数据库进程间锁PTHREAD_PROCESS_SHARED保证多个进程可以安全地并发读写名称约定/bcu_shared_data是跨进程 attach 的唯一标识常驻不退出用死循环维持共享内存生命周期代价是清理代码不可达
网站建设 高端定制 企业官网