gpt4 book ai didi

从同一进程创建 N 个子进程,然后打印所有子进程与相关父进程的 PID

转载 作者:行者123 更新时间:2023-11-30 19:02:25 25 4
gpt4 key购买 nike

我还是不明白为什么pid=11310的子进程会创建pid=11312的子进程

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>


int main(){
pid_t pid[2];
for (int i = 0; i<2; i++){
pid[i] = fork();
if ( pid[i] == 0){
printf("[child] pid %d from [parent] pid %d\n",getpid(),getppid());
}
}
}

我的预期:

[child] pid 11310 from [parent] pid 11309
[child] pid 11311 from [parent] pid 11309

但实际结果:

[child] pid 11310 from [parent] pid 11309
[child] pid 11311 from [parent] pid 11309
[child] pid 11312 from [parent] pid 11310

最佳答案

fork()通过复制调用进程来创建一个子进程,并从调用点开始将进程分成两部分。子进程和父进程运行在不同的内存空间1)。当时fork()两个内存空间具有相同的内容。这意味着子进程中的变量值与 fork() 时父进程的变量值相同。 .

for 的第一次迭代中循环:

pid[i] = fork(); 
// this will create child process and both parent and child process proceed with next statement

if ( pid[i] == 0){ // only child process will enter to this if block
printf("[child] pid %d from [parent] pid %d\n",getpid(),getppid());
}

打印的输出:

[child] pid 11310 from [parent] pid 11309

执行 for 后循环体,循环控制变量的值i由于i++,父进程和子进程地址空间都会增加.

因此,在第二次迭代中, i 的值是 1在父地址空间和子地址空间中。

现在都是 parent (PID: 11309)和 child (PID: 11310)将执行for循环体和两者都会创建一个子进程。这就是子进程 (PID: 11310) 的原因正在创建另一个 child (PID: 11312) .

             11309-----    --|
| | |---------> First iteration
11310 | --| --|
| | |---> Second iteration
11312 11311 --|

在第三次迭代中,i 的值将是2在所有 4进程和循环条件i<2将导致false并且所有进程都会退出。

您的代码中存在严重问题 - 如果父进程在子进程之前完成运行并退出,会发生什么情况?
在这种情况下,子进程将变为 orphan process你可能会得到父PID为1而不是原始的父进程 ID,因为孤立进程可能会重新定位到 init 进程,该进程通常分配有 PID 1

要解决这个问题,你必须让父级 wait在退出之前查看其所有子进程。

#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void) {
pid_t pid;

// You can take number of child process to be create as input from user

for (int i = 0; i < 2; i++) {
pid = fork();
if (pid == 0) {
printf("[child] pid %d from [parent] pid %d\n", getpid(), getppid());
break;
}
}

if (pid != 0) {
int cpid;
int status;
while ((cpid = wait(&status)) > 0)
printf("Parent (%d): child (%d) exited with status 0x%.4x\n", (int)getpid(), cpid, status);
}

return 0;
}
<小时/>

1)有一个称为写时复制的概念,这是一种优化,其中设置页表以便父进程和子进程开始共享所有相同的内存,并且仅在需要时复制任一进程写入的页面。这意味着父进程和子进程共享相同数据的副本,并且一旦其中任何一个进行写入,就会创建一个副本,并且一个进程内存中的任何更改在另一个进程中都是不可见的。

关于从同一进程创建 N 个子进程,然后打印所有子进程与相关父进程的 PID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55981611/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com