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

如何基于Boost Interprocess结合互斥锁与条件变量跨内存共享vector?

实现带互斥锁与条件变量的Boost Interprocess共享vector

我来帮你搞定这个跨进程安全共享vector的需求!你找到的基础代码已经实现了共享vector的核心,但要让它在多进程下安全访问,我们需要把互斥锁和条件变量也放在共享内存中(普通的std同步原语只能用于进程内线程)。下面是改造后的完整实现,包含生产者和消费者示例:

核心思路

  1. 用一个结构体封装共享资源:把interprocess_mutex、interprocess_condition和共享vector放在一起,确保所有进程都能访问到同一组同步原语。
  2. 使用Boost Interprocess的find_or_construct来安全创建/获取共享内存中的对象,避免重复初始化。
  3. 访问vector时必须先锁定互斥锁,操作完成后解锁;用条件变量实现生产者-消费者的同步(比如生产者通知消费者有新元素,消费者等待元素可用)。

完整代码示例

生产者进程代码

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <chrono>
#include <thread>
#include <iostream>

using namespace boost::interprocess;

// 定义共享内存中的分配器
using ShmemAllocator = allocator<int, managed_shared_memory::segment_manager>;
// 定义共享vector类型
using MyVector = vector<int, ShmemAllocator>;

// 封装共享资源的结构体,包含同步原语和vector
struct SharedData {
    interprocess_mutex mutex;
    interprocess_condition cond;
    MyVector vec;

    // 构造函数:用共享内存分配器初始化vector
    SharedData(const ShmemAllocator& alloc) : vec(alloc) {}
};

int main() {
    // 先清理可能存在的旧共享内存
    shared_memory_object::remove("MySharedMemory");

    // 创建共享内存段
    managed_shared_memory segment(create_only, "MySharedMemory", 65536);

    // 获取共享内存的分配器
    const ShmemAllocator alloc(segment.get_segment_manager());

    // 在共享内存中创建SharedData实例
    SharedData* shared_data = segment.construct<SharedData>("SharedData")(alloc);

    // 生产者逻辑:往vector里添加元素,然后通知消费者
    for (int i = 0; i < 5; ++i) {
        // 加锁
        scoped_lock<interprocess_mutex> lock(shared_data->mutex);
        shared_data->vec.push_back(i);
        std::cout << "Producer added: " << i << std::endl;
        // 通知等待的消费者
        shared_data->cond.notify_one();
        // 解锁(scoped_lock自动释放)
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }

    // 等待一下,让消费者有时间处理完所有元素
    std::this_thread::sleep_for(std::chrono::seconds(2));

    // 销毁共享内存中的对象(可选,也可以让消费者最后清理)
    segment.destroy<SharedData>("SharedData");
    shared_memory_object::remove("MySharedMemory");

    return 0;
}

消费者进程代码

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <iostream>

using namespace boost::interprocess;

// 复用和生产者相同的类型定义
using ShmemAllocator = allocator<int, managed_shared_memory::segment_manager>;
using MyVector = vector<int, ShmemAllocator>;

struct SharedData {
    interprocess_mutex mutex;
    interprocess_condition cond;
    MyVector vec;

    SharedData(const ShmemAllocator& alloc) : vec(alloc) {}
};

int main() {
    try {
        // 打开已存在的共享内存段
        managed_shared_memory segment(open_only, "MySharedMemory");

        // 查找共享内存中的SharedData实例
        SharedData* shared_data = segment.find<SharedData>("SharedData").first;
        if (!shared_data) {
            std::cerr << "Failed to find SharedData in shared memory!" << std::endl;
            return 1;
        }

        // 消费者逻辑:等待条件变量,然后读取vector元素
        for (int i = 0; i < 5; ++i) {
            scoped_lock<interprocess_mutex> lock(shared_data->mutex);
            // 等待直到vector中有元素(防止虚假唤醒,所以用while循环)
            while (shared_data->vec.empty()) {
                shared_data->cond.wait(lock);
            }
            // 取出最后一个元素
            int val = shared_data->vec.back();
            shared_data->vec.pop_back();
            std::cout << "Consumer received: " << val << std::endl;
        }
    } catch (const interprocess_exception& e) {
        std::cerr << "Interprocess error: " << e.what() << std::endl;
        shared_memory_object::remove("MySharedMemory");
        return 1;
    }

    return 0;
}

关键细节说明

  • 同步原语的位置:interprocess_mutex和interprocess_condition必须放在共享内存中,这样所有进程都能看到同一个锁和条件变量,普通的std::mutex只能用于进程内线程同步,不能跨进程。
  • scoped_lock的使用:它会自动管理锁的生命周期,避免手动解锁时出现遗漏或异常导致的死锁。
  • 条件变量的等待循环:必须用while循环检查条件,因为可能会出现虚假唤醒(条件变量在没有被通知的情况下也可能返回),循环能确保只有当条件满足时才继续执行。
  • 共享内存清理:如果进程异常退出,共享内存不会自动清理,所以最好在程序退出时(包括异常情况下)调用shared_memory_object::remove,或者在下次启动时先清理旧的共享内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:20:05