You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C语言实现共享内存?进程间数据共享有无比临时文件更优方案?

C语言多应用间数据共享方案优化建议

一、现有临时文件方案的核心问题

你当前基于临时文件的实现存在几个明显缺陷:

  • 读写依赖磁盘IO,性能远低于内存操作,哪怕是操作系统缓存的文件,也需要经过文件系统层的额外开销
  • 无并发控制:多个客户端同时写入temp.txt时会出现内容覆盖、文件损坏、读写冲突的问题
  • 延迟高、资源浪费:服务端采用100ms轮询的方式读取,数据更新不及时,空轮询也会占用不必要的CPU资源

二、更优方案:Windows平台命名共享内存实现

针对你的研究场景,共享内存是所有IPC方案中性能最高的,完全规避了磁盘IO开销,配合命名互斥量做并发控制,可以完美支持任意数量的客户端接入,适配你当前的Windows编译环境。

实现逻辑说明

  1. 调用Win32 API CreateFileMapping创建全局命名的共享内存段,大小根据你需要存储的数据量定义
  2. 调用MapViewOfFile将共享内存映射到当前进程的地址空间,直接读写内存地址即可完成数据交换
  3. 搭配全局命名的Mutex互斥量,保证同一时间只有一个进程在写共享内存,避免竞态条件
  4. 可选搭配事件(Event)通知服务端数据更新,不需要轮询,进一步降低延迟和CPU占用

三、修改后的代码示例

1. ipc.h

#ifndef IPC
#define IPC

// 共享内存、互斥量的全局命名,任意进程都可以通过名称打开
#define SHM_NAME "Global\\MySharedMemory"
#define MUTEX_NAME "Global\\MySharedMutex"
#define SHM_SIZE 256 // 共享内存大小,可根据需求调整

void write_message(int ID);
void read_message();

#endif

2. ipc.c

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include "ipc.h"

// 共享内存和互斥量的句柄,进程内全局持有
static HANDLE hMapFile = NULL;
static HANDLE hMutex = NULL;
static LPCTSTR pBuf = NULL;

// 初始化共享内存和互斥量,每个进程调用一次
static int init_ipc() {
    if (hMapFile != NULL && pBuf != NULL && hMutex != NULL) {
        return 0;
    }
    // 创建/打开互斥量
    hMutex = CreateMutex(NULL, FALSE, MUTEX_NAME);
    if (hMutex == NULL) {
        printf("CreateMutex error: %d\n", GetLastError());
        return -1;
    }
    // 创建/打开共享内存
    hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,    // 用系统页文件做 backing,不需要物理磁盘文件
        NULL,                    // 默认安全属性
        PAGE_READWRITE,          // 读写权限
        0,                       // 高位大小
        SHM_SIZE,                // 低位大小
        SHM_NAME);               // 全局命名
    if (hMapFile == NULL) {
        printf("CreateFileMapping error: %d\n", GetLastError());
        CloseHandle(hMutex);
        hMutex = NULL;
        return -1;
    }
    // 映射到进程地址空间
    pBuf = (LPTSTR)MapViewOfFile(
        hMapFile,                // 共享内存句柄
        FILE_MAP_ALL_ACCESS,     // 读写权限
        0,
        0,
        SHM_SIZE);
    if (pBuf == NULL) {
        printf("MapViewOfFile error: %d\n", GetLastError());
        CloseHandle(hMapFile);
        CloseHandle(hMutex);
        hMapFile = NULL;
        hMutex = NULL;
        return -1;
    }
    return 0;
}

void write_message(int ID) {
    if (init_ipc() != 0) {
        exit(1);
    }
    // 加锁,保证独占写入
    WaitForSingleObject(hMutex, INFINITE);
    // 直接写共享内存,和写普通内存操作完全一致
    sprintf((char*)pBuf, "ID\t:\t%d\n", ID);
    // 释放锁
    ReleaseMutex(hMutex);
}

void read_message() {
    if (init_ipc() != 0) {
        exit(1);
    }
    // 读操作可以不加锁,或者加共享锁,这里简单处理直接读
    printf("%s", (char*)pBuf);
}

3. client.c 无需修改,和原代码逻辑一致

#include <stdlib.h>
#include <stdio.h>
#include "ipc.h"

int main()
{
    int ID;
    while(1){   
        printf("Please enter ID: ");
        scanf("%d", &ID);
        write_message(ID);
    }
    return 0;
}

4. server.c 可保留原轮询逻辑,也可后续加事件通知优化

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include "ipc.h"

int main()
{
    while(1){
        read_message();
        Sleep(100);
    }
    return 0;
}

四、可扩展优化点

  • 去掉轮询逻辑:新增一个全局命名的Event对象,客户端写完数据后调用SetEvent通知服务端,服务端用WaitForSingleObject等待事件触发,不需要空转Sleep,延迟可以降到微秒级
  • 支持多数据缓存:如果需要保存多条客户端写入的记录,可以把共享内存改成环形队列结构,避免旧数据被直接覆盖
  • 跨平台适配:如果需要兼容Linux,可以换成POSIX共享内存接口shm_open + mmap,配合POSIX互斥量实现逻辑完全一致

内容的提问来源于stack exchange,提问作者Louis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 06:24:00