【问题标题】:Uneven tree of processes using fork()使用 fork() 的不均匀进程树
【发布时间】:2012-05-13 13:40:12
【问题描述】:

我必须在 C 中使用 fork() 构建一个进程树。我从标准输入中得到一个数字序列(例如:1 5 0 3),这些数字告诉我每个节点有多少个子节点。如果我们举个例子,那么根进程会创建 1 个子进程,然后这个子进程会创建自己的 5 个子进程,然后从这 5 个子进程中,第一个不会创建任何子进程,第二个进程会创建其中的 3 个,然后我们重做。完成后,根进程调用pstree 绘制树。

这是示例的图片:

我的问题是如何从特定节点创建新子节点?一个需要创建 0 个新进程,下一个需要创建 3 个。我不知道如何区分,以便只有那个特定的孩子会产生新的孩子,而不是所有的孩子。另外我不确定如何使用pstree,因为当pstree 被调用时,树通常已经消失了。我知道我可以wait() 让孩子先执行,但最后一个没有任何孩子要等待,所以他们结束得太快了。

我已经编写了创建示例的代码。需要想法如何将其推广到不同的输入。也有人可以告诉我如何从这段代码中调用 pstree,因为我似乎无法让它工作。

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


int main() {

pid_t pid;
pid_t temppid;
pid_t temppid2;
int  root_pid;
int status;

root_pid = getpid();

pid = fork(); // creates a child from root
if (pid == 0) { // if child
    pid = fork(); // fork again (child#1)
    if (pid != 0) { // if not child of child#1
        temppid = getpid(); // get pid
        if (getpid() == temppid) { // create child#2
            pid = fork();
            if (pid == 0) {
                temppid2 = getpid();
                if (getpid() == temppid2) { // create child#1
                    fork();
                }
                if (getpid() == temppid2) { // create child#2
                    fork();
                }
                if (getpid() == temppid2) { // create child#3
                    fork();
                }
            }
        }
        if (getpid() == temppid) { // create child#3
            fork();
        }
        if (getpid() == temppid) { // create child#4
            fork();
        }
        if (getpid() == temppid) { // create child#5
            fork();
        }
    }
}
else {
    // create another child from root
    pid = fork();
        if (pid == 0) {
            // run pstree in this child with pid from root
        }
}

while (1) {
    sleep(1);
}
}

【问题讨论】:

  • pstree 不是通用的树打印实用程序,您不能为此使用它。对于您问题的另一部分:您的代码在哪里?没有人可以在不了解您如何编写树结构的情况下帮助您。
  • 为什么需要这样做?这是作业题吗?
  • 你得到的数字是深度优先还是广度优先(或其他)?这个例子没有说清楚。例如,如果示例中的第一个数字是 2,第二个数字是 1,那么第三个数字是描述根的第一个子进程的第一个子进程的子进程数还是第二个子进程的子进程数?根进程?
  • @Mat He 没有树结构。他想创建子进程的层次结构并使用 pstree 打印。
  • @ragezor 你知道你会如何做一个具体的例子吗?例如,您知道如何编写一个无需输入并为 1 5 0 3 创建模式的函数吗?

标签: c fork


【解决方案1】:

对于pstree,解决方案很简单——每个进程在完成它应该做的事情之后,都会进入睡眠状态(比如说,一分钟)。
然后你可以使用pstree 看看发生了什么。

对于正确的分叉次数,问题似乎在于解析输入,而不是分叉。
我将从编写读取输入的代码开始,而不是分叉,只是打印您要创建的进程树。一旦你清楚了这一点,它就不能正确地分叉了。

【讨论】:

  • 我仍然没有得到 pstree 的输出。我认为这是因为它们结束得太快了,但也许我做错了什么。这就是我所说的: execlp("pstree", "pstree", "-n", root_pid, NULL);睡眠(5);返回 0;
  • 为什么将pstree 作为应用程序的一部分运行?只需打开另一个终端并在那里运行pstree。无论如何,错误可能是root_pid是一个整数,应该是一个字符串。
  • execlp 成功后的任何指令都无关紧要,因为该进程已替换为新代码。在您的情况下, sleep 和 return 永远不会被执行。如果 execlp 失败,则将执行 sleep 和 return。所以1)把printfs放在sleep 5周围。2)检查exec返回值是否成功。
  • 我认为最好不要使用execlp。如果您想要pstree 以查看您的代码是否有效,请从您的代码外部运行它。这样它就不会破坏它。
  • 我必须使用它,因为它是一个依赖于 pstree 输出的自动评分脚本。我现在从另一个终端运行它。
【解决方案2】:

仅用于测试您的应用创建的层次结构:

而不是放置一个

return 0; 

作为最后一个语句放一个

while (1)
  sleep(1);

这会使进程永远运行,直到您按下Ctrl-C

启动应用后,使用另一个终端并发出pstree 来检查应用创建的进程层次结构。

要清理(如果在 linux 上)发出 killall &lt;app name&gt;

【讨论】:

  • while (1) pause(); 会更干净。
【解决方案3】:

我的一个建议是您使用fork 的返回值来判断您的代码是在子进程还是父进程中运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多