这是我第一次用C编写代码并使用分叉,所以我对它有点困惑。我的任务是创建10个总进程=1个父进程、3个子进程和6个子进程。这是我目前正在努力解决的孙辈过程。
int i=0, j=0, child_count=1, grand_count=1;
for (i = 0; i < 3; i++) {
pid_t child = 0;
child = fork();
if (child != 0) {
for (j = 0; j < 2; j++) {
pid_t grand = 0;
grand = fork();
if (grand == 0){
printf("7I am grand #%d with PID %d and PPID %d\n", grand_count, getpid(), getppid());
exit(0);
}
grand_count++;
}
}
}我需要它打印:
我是大人物#6,PID 4373和PPID 745
我是大人物,PID 4372和PPID 745
我是大人物#4,PID 4370和PPID 745
我是大人物#3,PID 4369和PPID 745
我是大人物2,PID 4367和PPID 745
我是大人物,PID 4366和PPID 745
但是相反,我得到了:
我是大人物,PID 4372和PPID 745
我是大人物#4,PID 4370和PPID 745
我是大人物#6,PID 4373和PPID 745
我是大人物#3,PID 4369和PPID 745
我是大人物2,PID 4367和PPID 745
我是大人物,PID 4366和PPID 745
我是大人物#4,PID 4376和PPID 745
我是大人物#3,PID 4375和PPID 745
我是大人物#4,PID 4382和PPID 745
我是大人物#3,PID 4381和PPID 745
我是大人物2,PID 4379和PPID 745
我是大人物,PID 4378和PPID 745
我是大人物2,PID 4385和PPID 745
我是大人物,PID 4384和PPID 745
它按顺序打印(我假设是因为for循环,但我不知道如何修复它,所以欢迎您提供任何建议)。但我也不知道如何防止它多次打印相同的行。
发布于 2021-10-05 20:15:01
if (child != 0)是错误的,它后面的语句将由父进程执行。应该是if (child == 0)grand_count变量。它是从每个fork.上的当前父进程复制的。
示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
for(int i = 0; i < 3; i++) {
pid_t child = fork();
if(child == 0) {
for(int j = 0; j < 2; j++) {
pid_t grand = fork();
if(grand == 0) {
printf("I am grand child with PID %d and PPID %d\n",
getpid(), getppid());
exit(0);
}
}
// collect grand children
for(pid_t who_died; (who_died = wait(NULL)) != -1;) {
printf("grand child %d died\n", who_died);
}
exit(0); // and exit child
}
}
// collect children
for(pid_t who_died; (who_died = wait(NULL)) != -1;) {
printf("child %d died\n", who_died);
}
}可能的产出:
I am grand child with PID 2120874 and PPID 2120872
I am grand child with PID 2120876 and PPID 2120873
I am grand child with PID 2120877 and PPID 2120872
I am grand child with PID 2120878 and PPID 2120875
I am grand child with PID 2120880 and PPID 2120873
I am grand child with PID 2120883 and PPID 2120875
grand child 2120874 died
grand child 2120877 died
grand child 2120880 died
grand child 2120876 died
grand child 2120878 died
grand child 2120883 died
child 2120873 died
child 2120875 died
child 2120872 died发布于 2021-10-05 20:33:11
有几件事不对劲。
fork返回子进程的0。if (child != 0) {在父程序中运行(或一个错误)。grand_count.fork可能会非常令人困惑。在习惯它的同时,我鼓励使用基本的脚手架。
pid_t cpid = fork();
if (cpid == 0) {
child_function();
exit(0);
}
else if( cpid == -1 ) {
fork_error_handler();
}
// parent code通过将子代码放入一个空函数中,我们避免了嵌套循环和分叉。筑巢会使事情变得复杂。
考虑到这一点,我们可以重做您的外部循环,只执行派生子进程,并传递ID开始打印。
void fork_error_handler() {
perror("fork() failed");
}
void wait_all() {
// wait(NULL) waits for any child process to exit.
// If there are no more child processes, it returns -1.
// So to wait for all children to exit, keep calling wait
// until it returns -1.
while( wait(NULL) != -1 );
}
int main() {
int num_children = 2;
// From 0 to 2...
for (int i = 0; i <= num_children; i++) {
pid_t cpid = fork();
if (cpid == 0) {
// 1, 3, 5
spawn_printers(i * num_children + 1);
exit(0);
}
else if( cpid == -1 ) {
fork_error_handler();
}
}
wait_all();
}生成所有的子程序,但是将它们的代码放入一个函数中。这避免了嵌套叉和嵌套循环。
我们还确保等待直到我们的所有子进程完成。如果没有此操作,父程序将在子程序之前处理我的退出。这可能会导致孩子在父母离开时被杀死。
现在我们可以编写一个单独的函数来生成打印过程。
void spawn_printers(int starting_id) {
for (int i = 0; i < 2; i++) {
int id = starting_id + i;
pid_t cpid = fork();
if (cpid == 0) {
printf("I am grand #%d with PID %d and PPID %d\n", id, getpid(), getppid());
exit(0);
}
else if( cpid == -1 ) {
fork_error_handler();
}
}
// Each child has to wait for its own children.
wait_all();
}这些东西会打印出不正常的。这就是叉子的本质。如果你需要它按照特定的顺序打印,问另一个问题。
https://stackoverflow.com/questions/69456417
复制相似问题