C语言程序死锁问题求助:需让子进程2先于子进程1执行
问题原因分析
你的代码死锁的核心问题是信号量没有在进程间真正共享:
- 你在父进程的栈上定义了
sem_t sem,调用fork()后,子进程会复制父进程的栈空间,所以子进程1和子进程2各自拥有一个独立的sem副本,完全没有关联。 - 子进程2调用
sem_post(&sem)是给自己的信号量加1,而子进程1等待的是自己那个初始值为0的信号量,永远不会被唤醒,最终导致死锁。 - 另外,子进程1里调用
sem_destroy(&sem)也不合理,信号量的销毁应该由最后使用它的进程(通常是父进程)来执行。
修复方案
要实现进程间信号量共享,需要将信号量放在进程共享的内存区域(比如共享内存、匿名映射内存),或者使用有名信号量。下面是基于匿名共享内存的修复版本:
#include <stdio.h> #include <unistd.h> #include <semaphore.h> #include <sys/wait.h> #include <sys/mman.h> #include <fcntl.h> int main() { int pid1, pid2; // 用mmap创建匿名共享内存,存放信号量 sem_t *sem = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (sem == MAP_FAILED) { perror("mmap failed"); return 1; } // 初始化信号量,pshared设为1(进程间共享),初始值0 sem_init(sem, 1, 0); pid1 = fork(); if (pid1 == 0) { // child 1 sem_wait(sem); printf("Child 1 PID: %d\n", getpid()); munmap(sem, sizeof(sem_t)); // 释放映射 return 0; } else { // parent pid2 = fork(); if (pid2 == 0) { // child 2 printf("Child 2 PID: %d\n", getpid()); sem_post(sem); munmap(sem, sizeof(sem_t)); // 释放映射 return 0; } else { // parent wait(NULL); // wait for child 2 wait(NULL); // wait for child 1 sem_destroy(sem); // 销毁信号量 munmap(sem, sizeof(sem_t)); // 释放映射 printf("Parent PID: %d\n", getpid()); } } return 0; }
关键修改点
- 使用
mmap创建匿名共享内存,让父子进程的信号量指向同一块内核内存区域,实现真正的进程间共享。 - 移除子进程中的
sem_destroy,由父进程在所有子进程结束后销毁信号量。 - 每个进程结束前调用
munmap释放共享内存映射。
内容的提问来源于stack exchange,提问作者MwahMallah
相关产品推荐
相关产品推荐

