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

共享内存中Condition Variable无法唤醒休眠进程问题求助

问题分析与解决方法

核心问题

你遇到的问题根源在于**std::mutex和std::condition_variable不是进程间同步原语**,它们的设计目标是同一进程内的线程同步,内部状态(如等待队列、线程标识)属于进程私有数据。跨进程共享内存使用时,两个进程的同步原语实例无法感知彼此的状态,导致P2的wait调用永远无法被P1的notify唤醒。

修复方案

改用支持进程间同步的POSIX原语(pthread_mutex_t和pthread_cond_t),通过配置进程共享属性实现跨进程同步,具体修改如下:

1. 修改共享内存结构体定义

替换标准库同步对象为POSIX同步类型:

#include <pthread.h>

struct data_in_shm {
    int stuff;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
};

2. 初始化共享内存时配置进程共享属性

在创建并映射共享内存后,初始化同步原语的进程共享属性:

// P1中创建共享内存并映射完成后执行
pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init(&mutex_attr);
// 设置为进程间共享
pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&shm_data->mutex, &mutex_attr);
pthread_mutexattr_destroy(&mutex_attr);

pthread_condattr_t cond_attr;
pthread_condattr_init(&cond_attr);
pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
pthread_cond_init(&shm_data->cond, &cond_attr);
pthread_condattr_destroy(&cond_attr);

shm_data->stuff = 0; // 初始化变量

3. 修改P1的唤醒逻辑

替换标准库锁操作为POSIX mutex调用:

void wake_thread(data_in_shm* shm_data) {
    while (true) {
        sleep(1);
        pthread_mutex_lock(&shm_data->mutex);
        printf("P1: stuff is %d\n", shm_data->stuff);
        pthread_cond_signal(&shm_data->cond); // 唤醒等待的进程/线程
        pthread_mutex_unlock(&shm_data->mutex);
    }
}

4. 修改P2的等待递增逻辑

替换为POSIX同步操作,同时添加虚假唤醒防护:

void increment_thread(data_in_shm* shm_data) {
    while (true) {
        pthread_mutex_lock(&shm_data->mutex);
        // 等待唤醒,自动释放锁,唤醒后重新获取锁
        pthread_cond_wait(&shm_data->cond, &shm_data->mutex);
        shm_data->stuff++;
        printf("P2: incremented stuff to %d\n", shm_data->stuff);
        pthread_mutex_unlock(&shm_data->mutex);
    }
}

5. 编译时链接pthread库

编译命令需添加-lpthread参数:

g++ p1.cpp -o p1 -lpthread
g++ p2.cpp -o p2 -lpthread

额外注意事项

  • 虚假唤醒:pthread_cond_wait可能因系统原因触发虚假唤醒,若业务逻辑需要,可在等待前添加条件判断(比如检查是否有实际的唤醒信号)。
  • 资源清理:使用完共享内存后,需调用pthread_mutex_destroy、pthread_cond_destroy销毁同步原语,并正确释放共享内存资源,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:15:33