我在fork()
下的代码是一个创建其Child的进程,它们都调用相同的函数,该函数基本上会有一个循环。在内部,他们会在0到5之间随机睡眠几秒钟,然后打印一条愚蠢的消息,显示通过的过程已结束。最后,他们打印一条“正在退出”消息并离开。
问题在于,即使子级在完成之前仍是1或2遍,每次子级打印“退出”消息时,父级(显然)也会打印相同的消息。父项完成后,它将再次打印“退出”消息。如果父项在子项之前完成,它将在其完成时打印“退出”消息,并在子项完成时再次打印。
现在,如果我退出或返回Child if子句,则在函数执行完之后,将不显示“退出”父项消息。这使我相信孩子正在代表父母打印“退出”消息。那么,是什么导致父“退出”消息被打印两次?
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
const int PASS = 5;
const int RANDLIMIT = 5;
int i = 0;
void doSomeWork(char *who);
int main(int argc, char *argv[])
{
printf("Just started, I am: %d\n", (int) getpid());
pid_t pid = fork();
printf("fork returned: %d\n", (int) pid);
srand((int) pid);
if (pid < 0) {
perror("fork failed");
} else if (pid == 0) {
doSomeWork("Child");
// if I exit(0) or return(0) here, it behaves accordingly.
}
doSomeWork("Parent");
return(0);
}
void doSomeWork(char *who)
{
int control = 0;
for(; i < PASS; i++){
sleep(rand() % RANDLIMIT);
printf("%s: Done pass #%d\n", who, i);
}
printf("%s: exiting...\n", who);
}
孩子先完成:
[root@centos ~]# ./fork3
Just started, I am: 18232
fork returned: 18233
fork returned: 0
Child: Done pass #0
Parent: Done pass #0
Child: Done pass #1
Child: Done pass #2
Child: Done pass #3
Parent: Done pass #1
Parent: Done pass #2
Child: Done pass #4
Child: exiting...
Parent: exiting...
Parent: Done pass #3
Parent: Done pass #4
Parent: exiting...
父母先完成:
[root@centos ~]# ./fork3
Just started, I am: 19507
fork returned: 19508
Parent: Done pass #0
Parent: Done pass #1
fork returned: 0
Child: Done pass #0
Parent: Done pass #2
Parent: Done pass #3
Child: Done pass #1
Child: Done pass #2
Child: Done pass #3
Parent: Done pass #4
Parent: exiting...
[root@centos ~]# Child: Done pass #4
Child: exiting...
Parent: exiting...
答案 0 :(得分:2)
您同时在父母和孩子的{em> 中呼叫doSomeWork("Parent")
。这就是exit
使之起作用的原因-然后孩子在调用doSomeWork("Parent")
之前就终止了。
解决方案是:
if (pid < 0) {
perror("fork failed");
} else if (pid == 0) {
doSomeWork("Child");
} else {
doSomeWork("Parent");
}
当然,请记住,两个进程同时运行,因此执行顺序是不可预测的(通常会遇到多任务处理问题)。