创建特定的进程树并终止它

创建特定的进程树并终止它

我目前正在上计算机系统课程,但遇到了家庭作业问题。我必须创建这个特定的进程树:

流程树

我还需要它保持这种状态一段时间(使用 sleep()),以便用户可以使用 pstree 在终端中查找它并查看它是否存在。然后它必须向后终止(首先是 D,然后是 B,然后是 C)。到目前为止,我可以创建树,但 C 项在树的其余部分创建之前终止,所以我最终只能得到 A->B->D。我知道这是因为我的 exit(1) 行而发生的,但我不知道还能把它放在哪里,或者是否还有其他方法。

到目前为止我的代码:

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

int main() {

int status = 0;
printf("I am: %d\n\n", (int)getpid());
pid_t pid = fork(); // fork a child

if(pid == 0)
{
    printf("Hi I'm process %d and my parent is %d\n",getpid(),getppid());
    exit(1);
}
else
{
    pid_t childPid = wait(&status);
    int childReturnValue = WEXITSTATUS(status);
    printf("parent knows child %d finished with return value %d\n\n", (int) childPid, childReturnValue);

    pid_t pid = fork(); // fork a child
    if (pid == 0)
    {
        printf("Hi I'm process %d and my parent is %d.\n", getpid(), getppid());
        pid = fork(); // fork a child
        if (pid == 0)
        {
            printf("Hi I'm process %d and my parent is %d.\n",getpid(),getppid());
            exit(3);
        }
        else
        {
            pid_t childPid = wait(&status);
            int childReturnValue = WEXITSTATUS(status);
            printf("parent knows child %d finished with return value %d\n\n", (int) childPid, childReturnValue);
        }
        exit(2);
    }
    else
    {
        pid_t childPid = wait(&status);
        int childReturnValue = WEXITSTATUS(status);
        printf("parent knows child %d finished with return value %d\n\n", (int) childPid, childReturnValue);
    }
}

return 0;
}

这是我当前得到的输出:

I am: 2827

Hi I'm process 2828 and my parent is 2827
parent knows child 2828 finished with return value 1

Hi I'm process 2829 and my parent is 2827.
Hi I'm process 2830 and my parent is 2829.
parent knows child 2830 finished with return value 3

parent knows child 2829 finished with return value 2

理想情况下,“parent Knows child 2828 finish with a return value 1”这行应该一直放在最后。提前致谢!

答案1

你必须使用sleep来阻止C立即退出。但在你的结构中,A 等待 C 退出,然后再生成 B 和 D。

所以 :

  • 将 C 的块放在与B 的块wait相同的位置wait
  • 在C退出之前添加睡眠(也在B和D退出之前)
  • 因为你不想等待 B 两倍的时间,所以确保 B 的睡眠在 D 的等待之前
  • 要获得每个子流程的正确返回值,您应该使用waitpid而不是wait.

这是完整的代码:

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

#define SLEEP_TIME 5

int main() {

int status;
printf("I am: %d\n\n", (int)getpid());
pid_t c_pid = fork(); // fork a child

if(c_pid == 0)
{
    printf("Hi I'm process C (%d) and my parent is %d\n",getpid(),getppid());
    sleep(SLEEP_TIME);
    exit(1);
}
else
{
    pid_t b_pid = fork(); // fork a child
    if (b_pid == 0)
    {
        printf("Hi I'm process B (%d) and my parent is %d.\n", getpid(), getppid());
        pid_t d_pid = fork(); // fork a child
        if (d_pid == 0)
        {
            printf("Hi I'm process D (%d) and my parent is %d.\n",getpid(),getppid());
            sleep(SLEEP_TIME);
            exit(3);
        }
        else
        {
            // sleep before wait - actually no effect as the wait for D also waits for SLEEP_TIME
            sleep(SLEEP_TIME);
            // Wait for D to quit
            waitpid(d_pid, &status, 0);
            int DReturnValue = WEXITSTATUS(status);
            printf("parent knows child D (%d) finished with return value %d\n\n", (int) d_pid, DReturnValue);
        }
        exit(2);
    }
    else
    {
      sleep(SLEEP_TIME);

      // Wait for B to quit
      waitpid(b_pid, &status, 0);
      int BReturnValue = WEXITSTATUS(status);
      printf("parent knows child B (%d) finished with return value %d\n\n", (int) b_pid, BReturnValue);

      // Wait for C to quit
                                    waitpid(c_pid, &status, 0);
      int CReturnValue = WEXITSTATUS(status);
      printf("parent knows child C (%d) finished with return value %d\n\n", (int) c_pid, CReturnValue);
    }
}

return 0;
}

这是相应的输出:

我是:24450

您好,我是进程 C (24451),我的父进程是 24450

您好,我是进程 B (24452),我的父进程是 24450。

您好,我是进程 D (24453),我的父进程是 24452。

父级知道子级 D (24453) 已完成并返回值 3

父级知道子级 B (24452) 已完成并返回值 2

父级知道子级 C (24451) 已完成并返回值 1

相关内容