让我们从您当前代码的问题开始:
-
您不会通过在需要时显式终止子代码来分离父/子代码。您代码中的每个子代都将继续执行for 循环,然后执行wait() 之后的代码,这只能由父代执行。
-
你不是在等所有的孩子。如果您创建 3 个孩子,则需要拨打 3 个wait() 电话,每个孩子一个。在您的情况下,顺序并不重要,因此您可以使用 wait() 而不是 waitpid()/wait3()/wait4(),但您需要另一个循环。
-
您没有检查您使用的任何功能的错误。你绝对应该!
-
我有点错过了var 变量的要点,如果只是为了避免在子代码中输入循环体,那么简单的break、exit() 或return 就足够了.
您的代码的正确版本如下:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
int main() {
unsigned i;
int status;
pid_t child_pid;
printf("I am the Parent, my PID: %d\n", getpid());
for (i = 0; i < 3; i++) {
child_pid = fork();
if (child_pid == -1) {
perror("fork() failed");
return 1;
} else if (child_pid == 0) {
printf("Child: PID: %d; PPID: %d\n", getpid(), getppid() );
sleep(3);
printf("Child %d says bye!\n", getpid());
return 0;
}
}
for (i = 0; i < 3; i++) {
child_pid = wait(&status);
if (child_pid == -1) {
perror("wait() failed");
return 1;
}
if (WIFEXITED(status)) {
printf("Child %d exited with code %d\n", child_pid, WEXITSTATUS(status));
} else {
// Handle other cases here like WIFSIGNALED, WIFSTOPPED, etc...
// See `man 2 wait` for more information.
}
}
return 0;
}
我如何显示/证明所有进程可以同时存在?
这可以通过很多不同的方式来完成。您可以在生成 3 个孩子后使用 ps 之类的程序在另一个终端上从外部执行此操作(也许将睡眠时间增加到 10 秒以获得更多时间):
$ ps --ppid 249626 # get this from the output of your program
PID TTY TIME CMD
249627 pts/1 00:00:00 test
249628 pts/1 00:00:00 test
249629 pts/1 00:00:00 test
或者您可以通过在子代码中打印程序中执行的开始和结束时间来做到这一点:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <time.h>
void print_time(void) {
time_t t;
struct tm *local;
const char *local_str;
t = time(NULL);
if (t == (time_t)-1) {
perror("time() failed");
return;
}
local = localtime(&t)
if (local == NULL) {
perror("localtime() failed");
return;
}
local_str = asctime(&local);
if (local_str == NULL) {
perror("asctime() failed");
return;
}
ptintf("Child %d time: %s\n", getpid(), local_str);
}
// ... same code as before ...
} else if (child_pid == 0) {
printf("Child %d PPID: %d\n", getpid(), getppid() );
print_time();
sleep(3);
printf("Child %d says bye!\n", getpid());
print_time();
return 0;
}
// ... same code as before ...
输出:
I am the Parent, my PID: 250469
Child 250470 PPID: 250469
Child 250471 PPID: 250469
Child 250470 time: Tue Oct 26 23:53:03 2021
Child 250472 PPID: 250469
Child 250471 time: Tue Oct 26 23:53:03 2021
Child 250472 time: Tue Oct 26 23:53:03 2021
Child 250470 says bye!
Child 250470 time: Tue Oct 26 23:53:06 2021
Child 250471 says bye!
Child 250471 time: Tue Oct 26 23:53:06 2021
Child 250472 says bye!
Child 250472 time: Tue Oct 26 23:53:06 2021
Child 250470 exited with code 0
Child 250471 exited with code 0
Child 250472 exited with code 0