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

在对象构造函数中打开Boost Interprocess段引发的访问冲突问题

问题原因及解决方案

核心问题原因

你遇到的访问违例本质是共享内存映射被提前卸载导致悬空指针:

  • Communication构造函数中创建的managed_shared_memory segment是局部变量,构造函数执行完毕后该对象会被销毁。Boost Interprocess的managed_shared_memory是RAII类型,销毁时会自动解除当前进程对共享内存的映射。
  • 你保存的map指针指向共享内存中的地址,一旦映射被卸载,这个地址就变成无效的悬空指针,后续调用addData访问map时必然触发内存访问错误。

可行的修正方案

完全可以按你最初的思路使用Boost Interprocess,只需调整Communication类的结构,让managed_shared_memory的生命周期覆盖map的整个使用周期:

// 子进程代码(注入DLL的进程)
class Communication{
    managed_shared_memory segment; // 作为类成员,维持共享内存映射
    Int_Vector_Map* map;

public:
    Communication() : segment(open_only, "Shared") { // 初始化列表中构造segment
        map = segment.find<Int_Vector_Map>("Map").first;
    }
    void addData(int _key, int _value){
        if(map->size() == 0 || map->find(_key) == map->end()){
            Int_Allocator alloc = segment.get_segment_manager(); // 使用类成员的segment获取分配器
            map->insert(Int_Vector_Map_Type(_key, Int_Vector(alloc)));
        }
        map->at(_key).push_back(_value);
    }
};

关键修改点

  • 将managed_shared_memory改为Communication类的成员变量,使其生命周期与Communication对象一致,只要对象存在,共享内存映射就会保持有效。
  • 在构造函数初始化列表中创建segment,避免局部临时对象的销毁问题。
  • addData中直接使用类成员的segment获取分配器,无需重复打开共享内存。

额外注意事项

  • 多进程访问共享内存必须添加同步机制(比如interprocess_mutex),否则多个进程同时写入map会引发数据竞争,导致未定义行为。当前代码缺少同步,即使修复悬空指针问题,也可能出现数据损坏。
  • 确保父进程创建的共享内存未被提前销毁,否则子进程访问时同样会出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:52:37