Minix2中fork()子进程父PID异常显示为12的问题排查求助
问题分析与解决方案
核心问题原因
你的测试代码存在两处致命逻辑错误,导致子进程被Minix的init进程(PID12)收养,从而出现所有子进程父PID显示为12的现象:
未初始化的变量导致分支逻辑混乱:
只有在proc1 == 0的分支里才会给proc2赋值,其他进程中proc2是未初始化的垃圾值,后续的if (proc1 != 0 && proc2 != 0...)这类条件判断完全不可靠,导致父进程提前执行到wait甚至退出,子进程失去父进程后被init接管。wait调用逻辑错误:
所有进程都执行了6次wait(NULL),但大部分进程根本没有这么多子进程,会导致不必要的阻塞,甚至部分进程在wait期间退出,引发子进程被收养。
另外,你的系统调用代码存在一个小问题:prid变量未初始化,如果系统中没有进程(极端情况)会返回垃圾值,需要初始化为0或者合理默认值。
修正后的测试代码
#include <lib.h> #include <minix/callnr.h> #include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { Message m; int answ; pid_t prid; pid_t proc1, proc2, proc3, proc4, proc5, proc6; int children; int wait_count = 0; // 初始化所有进程变量为-1,避免垃圾值干扰判断 proc1 = proc2 = proc3 = proc4 = proc5 = proc6 = -1; proc1 = fork(); if (proc1 == 0) { proc2 = fork(); if (proc2 != 0) { proc3 = fork(); if (proc3 != 0) { proc4 = fork(); if (proc4 != 0) { proc6 = fork(); } } } } else { proc5 = fork(); } // 统计当前进程需要wait的子进程数量 if (proc1 > 0) wait_count++; if (proc2 > 0) wait_count++; if (proc3 > 0) wait_count++; if (proc4 > 0) wait_count++; if (proc5 > 0) wait_count++; if (proc6 > 0) wait_count++; // 只有原始父进程调用系统调用 if (proc1 != 0 && proc5 != 0) { // 等待所有子进程创建完成,避免统计时部分进程未初始化 sleep(1); answ = _syscall(MM, NEW_SYSCALL, &m); prid = m.m1_i1; children = m.m1_i2; printf("PID of process with biggest number of children: %d\n", prid); printf("Number of children: %d\n", children); printf("Test process: %d\n", getpid()); printf("Children: %d, %d, %d, %d, %d, %d\n", proc1, proc2, proc3, proc4, proc5, proc6); } // 只wait自己创建的子进程 for (int i = 0; i < wait_count; i++) { wait(NULL); } return 0; }
修正后的系统调用代码
PUBLIC int do_newsyscall(void) { int children = 0; pid_t prid = 0; // 初始化默认PID为0 struct mproc *proc; struct mproc *child; for (proc = mproc; proc < &mproc[NR_PROCS]; proc++) { if (proc->mp_flags & IN_USE) { int child_count = 0; for (child = mproc; child < &mproc[NR_PROCS]; child++) { if ((child->mp_flags & IN_USE) && child->mp_parent == proc->mp_pid) { child_count++; } } if (child_count > children) { children = child_count; prid = proc->mp_pid; } printf("pr:%d children: %d Father: %d\n", proc->mp_pid, child_count, proc->mp_parent); } } mproc[MM_in.M_source].mp_reply.m1_i1 = prid; mproc[MM_in.M_source].mp_reply.m1_i2 = children; return 1; }
关键修正点说明
- 初始化进程变量:将所有
procX变量初始化为-1,避免未初始化的垃圾值导致条件判断错误。 - 重构fork逻辑:使用嵌套的if结构,确保只有当前进程确实是父进程时才创建下一个子进程,避免分支混乱。
- 按需wait:统计当前进程实际创建的子进程数量,只wait对应次数,避免不必要的阻塞和提前退出。
- 系统调用变量初始化:给
prid设置默认值0,避免极端情况下返回垃圾值。
内容的提问来源于stack exchange,提问作者Ivashchenko Matvii
相关产品推荐
相关产品推荐

