首页 > 解决方案 > 如何打印由c中的fork命令创建的进程树

问题描述

我通过组合 C 中的 fork 命令创建了一个 fork 树。创建树的程序是:

int main(){

    (fork()&&(fork()&&(fork()||(fork()&&fork())&&fork())||(fork()||(fork()&&fork()))))||(fork()||(fork()&&fork()));

    while(1);

    return 0;
}

该命令写在 C 文件中。如何打印此代码创建的进程树?

标签: cprocesstreefork

解决方案


我会让程序以 Graphviz DOT 格式打印出树,作为有向图。在你的情况下,输出将沿着

digraph {
    "a" -> "b";
    "a" -> "c";
    "b" -> "d";
}

其中每个进程(除了第一个进程)打印一行,其中包含->:右侧引号中的其自己的 PID,左侧引号中其父 PID。

初始进程打印digraph {}部分,但请注意每个进程必须等待其子进程才能}最后打印结束。您可以通过在该行之前保存进程 ID 来做到这一点,并在收获所有子进程后,}如果此进程 ID 与原始进程 ID 匹配,则打印结束。

要收获孩子,请用例如替换您的无限循环

pid_t  p;

while (1) {
    p = wait(NULL);
    if (p == -1 && errno != EINTR)
        break;
}

它一直等到当前进程的所有子进程都退出。

在 Linux 系统中,您的包/软件管理器将拥有 Graphviz 包,因此请从那里安装它。(对于非 Linux 系统,请参阅graphviz.org。)

运行您的程序,但将 DOT 输出重定向到一个文件,例如out.dot. 然后,运行dot -Tx11 out.dot以交互方式查看图形,或dot -Tsvg out.dot > out.svg生成out.svg可在任何浏览器中查看的 SVG 图像 ( )。

这是一个可能的 .dot 输出,经过适当修改的程序可以输出:

digraph {
    "944" -> "945";
    "944" -> "946";
    "944" -> "947";
    "947" -> "950";
    "945" -> "948";
    "947" -> "951";
    "946" -> "949";
    "950" -> "953";
    "947" -> "952";
    "948" -> "956";
    "951" -> "955";
    "949" -> "957";
    "948" -> "954";
    "953" -> "958";
    "957" -> "963";
    "955" -> "964";
    "949" -> "959";
    "953" -> "961";
    "955" -> "962";
    "963" -> "968";
    "952" -> "960";
    "959" -> "966";
    "962" -> "969";
    "963" -> "965";
    "958" -> "973";
    "960" -> "971";
    "964" -> "967";
    "969" -> "975";
    "973" -> "979";
    "961" -> "970";
    "973" -> "978";
    "966" -> "974";
    "967" -> "982";
    "969" -> "976";
    "960" -> "972";
    "970" -> "984";
    "972" -> "985";
    "971" -> "980";
    "966" -> "977";
    "980" -> "986";
    "967" -> "981";
    "970" -> "983";
    "985" -> "988";
    "980" -> "987";
    "985" -> "989";
}

推荐阅读