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

C++ 基于boost::interprocess共享内存的进程间信号通知方案咨询

进程间共享内存更新通知实现方案

场景说明

现有两个并行运行的进程,分别负责向共享内存写数据、从共享内存读数据,已基于boost::interprocess实现共享内存读写逻辑,需要实现写操作完成后实时通知读进程数据更新,适配实时数据流传输场景。

现有实现代码(写进程)

//Writer
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/windows_shared_memory.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>

namespace ip = boost::interprocess;
class SharedMemory
{
public:
    template<typename OpenOrCreate>
    SharedMemory(OpenOrCreate criteria, const char* name, ip::mode_t mode, size_t size) :
        name_(name),
        sm_(std::make_shared<ip::windows_shared_memory>(criteria, name, mode, size))
    {
    }

    template<typename OpenOrCreate>
    SharedMemory(OpenOrCreate criteria, const char* name, ip::mode_t mode) :
        name_(name),
        sm_(std::make_shared<ip::windows_shared_memory>(criteria, name, mode))
    {
    }

    std::shared_ptr<ip::windows_shared_memory> getSM()
    {
        return sm_;
    }
private:
    std::function<void()> destroyer_;
    std::string name_;
    std::shared_ptr<ip::windows_shared_memory> sm_;
};


int main()
{
    SharedMemory creator(ip::create_only, "SharedMemory", ip::read_write, 10);
    ip::mapped_region region(*creator.getSM(), ip::read_write);
    std::memset(region.get_address(), 1, region.get_size());

    int status = system("reader.exe");
    std::cout << status << std::endl;
}

推荐实现方案

方案1:使用boost::interprocess自带同步组件(无额外依赖,优先推荐)

直接使用库自带的named_mutex+named_condition组合,和现有共享内存逻辑完全兼容:

写进程修改逻辑

  1. 新增头文件引入:
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
  1. 写数据前后的同步逻辑:
int main()
{
    // 启动前先清理可能残留的同步对象,避免异常退出导致的启动失败
    ip::named_mutex::remove("shm_mutex");
    ip::named_condition::remove("shm_cond");

    SharedMemory creator(ip::create_only, "SharedMemory", ip::read_write, 10);
    ip::mapped_region region(*creator.getSM(), ip::read_write);
    
    // 创建命名互斥锁和条件变量
    ip::named_mutex mutex(ip::create_only, "shm_mutex");
    ip::named_condition cond(ip::create_only, "shm_cond");

    // 写数据
    {
        ip::scoped_lock<ip::named_mutex> lock(mutex);
        std::memset(region.get_address(), 1, region.get_size());
    }
    // 解锁后再发送通知,减少不必要的阻塞
    cond.notify_one();

    // 其他业务逻辑...
}

读进程修改逻辑

int main()
{
    SharedMemory opener(ip::open_only, "SharedMemory", ip::read_only);
    ip::mapped_region region(*opener.getSM(), ip::read_only);

    // 打开同名的互斥锁和条件变量
    ip::named_mutex mutex(ip::open_only, "shm_mutex");
    ip::named_condition cond(ip::open_only, "shm_cond");

    {
        ip::scoped_lock<ip::named_mutex> lock(mutex);
        // 等待写进程通知
        cond.wait(lock);
        // 收到通知后读取数据
        char* data = static_cast<char*>(region.get_address());
        // 处理数据逻辑...
    }
    // 其他业务逻辑...
}

方案2:Windows原生命名事件(仅Windows平台,用法更简单)

因为当前用的是windows_shared_memory,仅运行在Windows平台的话可以直接用系统API的命名事件,逻辑更轻量:

  • 写进程调用CreateEventA创建命名事件,写完数据后调用SetEvent触发通知
  • 读进程调用OpenEventA打开同名事件,调用WaitForSingleObject等待事件触发后再读数据

方案3:命名信号量

如果逻辑更简单不需要额外条件判断,也可以用boost::interprocess::named_semaphore,写进程写完调用post(),读进程调用wait()等待即可。

注意事项

  • 实时数据流场景可以在共享内存中新增一个序列号字段,读进程被唤醒后比对序列号,避免因信号丢失导致的漏读问题
  • 同步对象的名称要全局唯一,避免和其他进程冲突
  • 进程退出前可以主动清理创建的同步对象,避免残留影响下次启动

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 08:39:00