我遇到了以下问题。我需要在 Minix2(minix204) 操作系统中编写一个系统调用,该系统调用将返回具有最大子进程数量的进程的 pid。我设法编写了调用函数,但在测试阶段遇到了问题。我尝试使用 fork() 进行测试,创建了 6 个进程,但由于某种原因,它们总是获得与创建它们的进程不同的父 pid。无论启动它们的进程是什么pid,它们都获得父pid 12。我完全不知道为什么会发生这种情况,我将附上屏幕截图和代码(代码是从屏幕截图中扫描的,我试图修复所有拼写错误,但它们是可能的。初始代码已编译并运行。)输出(它包含有关所有带有 IN_USE 标志的进程、主进程和子进程的 pid 的信息)、测试函数的代码和的代码实现系统调用的函数。我尝试在调用之前在主进程中添加延迟,但这不起作用。我希望得到你的支持,因为我已经没有想法了。 Minix 运行在 VMware Workstation 17 Player 上。谢谢。 输出、测试函数1、测试函数2、系统调用函数1、系统调用函数2输出:
# ./test1
pr:0 children: 4 Father: 0
pr:0 children:3 Father: 0
pr:1 children: 0 Father: 0
pr:3 children: 1 Father: 2
pr:13 children: 0 Father: 3
pr:0 children: 1 Father: 0
pr:19 children: 0 Father: 4
pr:20 children: 0 Father: 4
pr:21 children: 0 Father: 4
pr:22 children: 0 Father: 4
pr:23 children: 0 Father: 4
pr:25 children: 0 Father: 4
pr:26 children: 0 Father: 11
pr:27 children: 0 Father: 12
pr:28 children: 0 Father: 12
pr:29 children: 0 Father: 12
pr:30 children: 0 Father: 12
pr:31 children: 0 Father: 12
pr:32 children: 0 Father: 12
PID of process with biggest number of children: 0 Number of children: 4
Test proces: 26
Children:27, 28, 28, 29, 30, 31
#
测试功能:
#include <lib.h>
#include <minix/callnr.h>
#include <stdio.h>
#include <unistd.h>
int main() {
Message m;
int answ;
pid_t prid;
pid_t proc1, proc2, proc3, proc4, proc5, proc6;
int children;
proc1 = fork();
if (proc1 == 0) {
proc2 = fork();
}
if (proc1 == 0 && proc2 != 0) {
proc3 = fork();
}
if (proc1 == 0 && proc2 != 0 && proc3 != 0) {
proc4 = fork();
}
if (proc1 != 0 && proc2 != 0 && proc3 != 0 && proc4 != 0) {
proc5 = fork();
}
if (proc1 == 0 && proc2 != 0 && proc3 != 0 && proc4 != 0 && proc5 != 0) {
proc6 = fork();
}
if (proc1 == 0) {
sleep(3);
} else if (proc2 == 0) {
sleep(3);
} else if (proc3 == 0) {
sleep(3);
} else if (proc4 == 0) {
sleep(3);
} else if (proc5 == 0) {
sleep(3);
} else if (proc6 == 0) {
sleep(3);
} else {
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(NULL);
wait(NULL);
wait(NULL);
wait(NULL);
wait(NULL);
wait(NULL);
return 0;
}
系统调用函数:
PUBLIC int do_newsyscall(void) {
int children = 0;
pid_t prid;
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", proc->mp_pid);
printf(" children: %d Father: %d\n", 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;
}
问题出在系统调用函数中,因为 @JhonBollinger 注意到
mp_parent
是 mproc 中父级的索引。所以应该是这样
if ((child->mp_flags & IN_USE) && mproc[child->mp_parent].mp_pid == proc->mp_pid) {
child_count++;
}