跨进程共享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
相关产品推荐
相关产品推荐

