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

C++中fork()进程间共享列表与互斥锁的声明方法

实现进程间共享列表与互斥锁的两种方式

一、原生POSIX API实现

fork()创建的子进程会复制父进程的地址空间,但普通内存区域是各自独立的,因此必须通过共享内存存放需要共享的列表和互斥锁,同时互斥锁需配置为进程间可见的属性。

1. 核心要点

  • 共享内存区域:通过shm_open创建共享内存对象,再用mmap映射到进程地址空间,让父子进程访问同一块物理内存。
  • 进程间互斥锁:初始化pthread_mutex_t时,设置PTHREAD_PROCESS_SHARED属性,确保锁能跨进程生效。
  • 注意:标准STL容器(如std::list)默认使用堆内存分配,无法直接放入共享内存。如果要用STL容器,需要自定义分配器将内存分配到共享内存区域;或者改用C风格链表(节点全部放在共享内存中)。

2. 代码示例

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cstring>
#include <sys/wait.h>

// 定义共享内存中的结构体:包含互斥锁和固定大小的列表(模拟)
#define MAX_LIST_ITEMS 100
struct SharedData {
    pthread_mutex_t mutex;
    int list[MAX_LIST_ITEMS];
    int count; // 记录列表中元素的数量
};

int main() {
    // 创建共享内存对象
    int shm_fd = shm_open("/my_shared_memory", O_CREAT | O_RDWR, 0666);
    if (shm_fd == -1) {
        perror("shm_open failed");
        return 1;
    }

    // 设置共享内存大小
    ftruncate(shm_fd, sizeof(SharedData));

    // 映射共享内存到进程地址空间
    SharedData* shared_data = static_cast<SharedData*>(mmap(nullptr, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0));
    if (shared_data == MAP_FAILED) {
        perror("mmap failed");
        return 1;
    }

    // 初始化互斥锁的进程间共享属性
    pthread_mutexattr_t mutex_attr;
    pthread_mutexattr_init(&mutex_attr);
    pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&shared_data->mutex, &mutex_attr);
    pthread_mutexattr_destroy(&mutex_attr);

    // 初始化列表计数
    shared_data->count = 0;

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork failed");
        return 1;
    } else if (pid == 0) {
        // 子进程:向列表添加元素
        for (int i = 0; i < 10; ++i) {
            pthread_mutex_lock(&shared_data->mutex);
            if (shared_data->count < MAX_LIST_ITEMS) {
                shared_data->list[shared_data->count++] = i + 100;
                std::cout << "Child added: " << i + 100 << std::endl;
            }
            pthread_mutex_unlock(&shared_data->mutex);
            sleep(1);
        }
    } else {
        // 父进程:向列表添加元素
        for (int i = 0; i < 10; ++i) {
            pthread_mutex_lock(&shared_data->mutex);
            if (shared_data->count < MAX_LIST_ITEMS) {
                shared_data->list[shared_data->count++] = i;
                std::cout << "Parent added: " << i << std::endl;
            }
            pthread_mutex_unlock(&shared_data->mutex);
            sleep(1);
        }
        // 等待子进程结束
        wait(nullptr);

        // 打印最终列表
        pthread_mutex_lock(&shared_data->mutex);
        std::cout << "\nFinal list: ";
        for (int i = 0; i < shared_data->count; ++i) {
            std::cout << shared_data->list[i] << " ";
        }
        std::cout << std::endl;
        pthread_mutex_unlock(&shared_data->mutex);

        // 清理资源
        pthread_mutex_destroy(&shared_data->mutex);
        munmap(shared_data, sizeof(SharedData));
        shm_unlink("/my_shared_memory");
    }

    return 0;
}

编译时需链接pthread库:g++ -o shared_list shared_list.cpp -lpthread

二、Boost.Interprocess库实现

Boost.Interprocess专门为进程间通信设计,提供了开箱即用的共享内存容器和进程间同步原语,大幅简化代码,无需手动管理共享内存映射和锁属性。

1. 核心要点

  • 使用managed_shared_memory创建/打开共享内存区域。
  • 使用interprocess::list(带共享内存分配器)作为共享列表。
  • 使用interprocess::mutex作为进程间互斥锁,无需额外配置属性。

2. 代码示例

#include <iostream>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/list.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <unistd.h>
#include <sys/wait.h>

namespace bip = boost::interprocess;

// 定义共享内存中的数据结构
struct SharedData {
    bip::interprocess_mutex mutex;
    bip::list<int, bip::allocator<int, bip::managed_shared_memory::segment_manager>> list;

    // 构造函数:初始化列表(使用共享内存分配器)
    SharedData(bip::managed_shared_memory::segment_manager* sm) : list(sm) {}
};

int main() {
    // 先删除旧的共享内存(避免残留)
    bip::shared_memory_object::remove("/boost_shared_memory");

    // 创建共享内存区域
    bip::managed_shared_memory segment(bip::create_only, "/boost_shared_memory", 65536);

    // 在共享内存中构造SharedData对象
    SharedData* shared_data = segment.construct<SharedData>("SharedData")(segment.get_segment_manager());

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork failed");
        return 1;
    } else if (pid == 0) {
        // 子进程:添加元素
        for (int i = 0; i < 10; ++i) {
            bip::scoped_lock<bip::interprocess_mutex> lock(shared_data->mutex);
            shared_data->list.push_back(i + 100);
            std::cout << "Child added: " << i + 100 << std::endl;
            sleep(1);
        }
    } else {
        // 父进程:添加元素
        for (int i = 0; i < 10; ++i) {
            bip::scoped_lock<bip::interprocess_mutex> lock(shared_data->mutex);
            shared_data->list.push_back(i);
            std::cout << "Parent added: " << i << std::endl;
            sleep(1);
        }

        // 等待子进程结束
        wait(nullptr);

        // 打印最终列表
        bip::scoped_lock<bip::interprocess_mutex> lock(shared_data->mutex);
        std::cout << "\nFinal list: ";
        for (int num : shared_data->list) {
            std::cout << num << " ";
        }
        std::cout << std::endl;

        // 清理资源
        segment.destroy<SharedData>("SharedData");
        bip::shared_memory_object::remove("/boost_shared_memory");
    }

    return 0;
}

编译时需链接Boost库:g++ -o boost_shared_list boost_shared_list.cpp -lboost_system -lboost_interprocess

说明

  • Boost.Interprocess的容器自动使用共享内存分配器,无需担心内存分配位置问题。
  • scoped_lock是RAII风格的锁,能自动管理锁的释放,避免死锁风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:37:08