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

跨进程共享mutex时,父子进程需分别调用pthread_mutex_destroy吗?

关于父子进程共享互斥锁的销毁问题

完全没必要让父子进程分别调用pthread_mutex_destroy,反而这种做法会触发未定义行为,正确的做法是只在一个进程里执行一次销毁操作,通常是父进程等待子进程退出后再执行。

具体原因:

  • pthread_mutex_destroy的核心作用是清理互斥锁关联的内核资源,并将锁重置为未初始化状态。由于这个互斥锁设置了PTHREAD_PROCESS_SHARED属性,且存储在mmap映射的共享内存中,父子进程操作的是同一个锁实例。
  • 如果父子进程都调用销毁,就相当于对已经被销毁的锁再次执行销毁操作,这是POSIX标准明确禁止的未定义行为,可能引发程序崩溃、资源泄漏或其他难以排查的异常。
  • 代码中的pthread_mutexattr_destroy也存在同样问题:这个属性对象同样位于共享内存中,重复销毁会导致相同的未定义行为。

修正后的代码示例:

struct mt {
    pthread_mutex_t mutex;
    pthread_mutexattr_t mutexattr;
};

int main(void) {
    struct mt *mm;
    pid_t pid;

    int fd = open("my_name", O_CREAT | O_RDWR, 0777);
    ftruncate(fd, sizeof(*mm));
    mm = (struct mt *) mmap(NULL, sizeof(*mm), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);
    unlink("my_name");

    pthread_mutexattr_init(&mm->mutexattr);
    pthread_mutexattr_setpshared(&mm->mutexattr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&mm->mutex, &mm->mutexattr);


    pid = fork();
    if (pid == 0) {
        pthread_mutex_lock(&mm->mutex);
        doSomething();
        pthread_mutex_unlock(&mm->mutex);
        // 子进程直接退出,不执行销毁操作
        return 0;
    } else {
        pthread_mutex_lock(&mm->mutex);
        doSomething();
        pthread_mutex_unlock(&mm->mutex);
        wait(NULL);
        // 父进程在子进程退出后统一销毁锁和属性
        pthread_mutexattr_destroy(&mm->mutexattr);
        pthread_mutex_destroy(&mm->mutex);
    }

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:12:40