跨进程使用std::condition_variable同步时调用notify_all崩溃求助
问题原因与解决方案
核心原因
std::condition_variable(底层依赖pthread_cond_t)默认初始化时是进程私有的,内部包含仅当前进程有效的资源(如指向进程内等待队列的指针、线程本地状态等)。将这类未配置进程共享属性的同步原语放入共享内存后,其他进程调用notify_*时会访问无效内存,直接触发SIGSEGV。
而有名信号量sem_t本身设计就支持跨进程使用,无需额外配置,因此能正常工作。
正确实现步骤
要让pthread_cond_t和pthread_mutex_t支持跨进程同步,必须显式设置进程共享属性,且不能使用std::condition_variable(其封装未暴露进程共享配置接口)。具体操作如下:
定义共享内存结构(必须为POD类型)
struct SharedData { pthread_mutex_t mutex; pthread_cond_t cond; int counter; bool flag; };初始化共享内存中的互斥锁
仅由第一个创建共享内存的进程执行初始化,其他进程直接使用已初始化的对象:pthread_mutexattr_t mattr; pthread_mutexattr_init(&mattr); // 设置为进程共享模式 pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); // 初始化共享内存中的互斥锁 int ret = pthread_mutex_init(&shared_data->mutex, &mattr); pthread_mutexattr_destroy(&mattr); if (ret != 0) { // 处理初始化错误逻辑 }初始化共享内存中的条件变量
同样仅由第一个创建共享内存的进程执行:pthread_condattr_t cattr; pthread_condattr_init(&cattr); // 设置为进程共享模式 pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED); // 初始化共享内存中的条件变量 ret = pthread_cond_init(&shared_data->cond, &cattr); pthread_condattr_destroy(&cattr); if (ret != 0) { // 处理初始化错误逻辑 }使用与销毁注意事项
- 所有进程需以读写权限映射共享内存,确保同步原语和数据的正常访问。
- 销毁同步原语时,需确保所有进程已停止使用,由最后退出的进程调用
pthread_mutex_destroy和pthread_cond_destroy。
常见错误规避
- 禁止将
std::condition_variable或std::mutex放入共享内存:这些C++标准库封装的同步原语默认是进程私有,且无法配置为进程共享。 - 必须设置
PTHREAD_PROCESS_SHARED属性:缺少此配置会导致同步原语仅在当前进程内有效,跨进程访问必然崩溃。 - 避免重复初始化:多个进程重复初始化共享内存中的同步原语会导致未知错误,仅由创建共享内存的进程执行一次初始化。
内容的提问来源于stack exchange,提问作者raman
相关产品推荐
相关产品推荐

