c - 使用 fork() 显示进程树
问题描述
我需要创建一个进程树并在类似于此的图表中显示父级和子级:
但是我的结果看起来更像下图:
我不确定我做错了什么,这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void){
int i, status;
printf( "Enter a value for n :");
int n;
scanf("%d", &n);
FILE *file;
file = fopen("./digraph.txt", "w+"); //my output file
fprintf(file, "digraph {\n");
for (i=0; i<n; i++){
fflush(file);
int pid = fork();
if (pid == 0) {//child
if(i == 0) { //first level
fprintf(file, " \"%d\" [ label=\"pid %d, level %d\" ];\n", getppid(), getppid(), i, file);
fprintf(file, " \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i +1, file);
fprintf(file, " \"%d\" -> \"%d\";\n", getppid(), getpid(), file);
}else{
fprintf(file, " \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i , file);
fprintf(file, " \"%d\" -> \"%d\";\n", getppid(), getpid(), file);
}
}
else {
pid = waitpid(-1, &status, 0);
break;
}
}
if (i>n){
fprintf(file, "}");
fclose(file);
}
}
解决方案
正如我所说的......你fork()
在新创建的子进程中每次迭代只有一次。所以你不能真的期待像树一样的视图,对吧?
为了实现这一点,您可能需要在循环中执行以下操作:
for (i=0; i<n; i++){
fflush(file);
pid_l = fork();
if (pid_l == 0) { //left child
if(i == 0) { //first level
fprintf(file, " \"%d\" [ label=\"pid %d, level %d\" ];\n", getppid(), getppid(), i);
fprintf(file, " \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i + 1);
fprintf(file, " \"%d\" -> \"%d\";\n", getppid(), getpid());
}else{
fprintf(file, " \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i + 1);
fprintf(file, " \"%d\" -> \"%d\";\n", getppid(), getpid());
}
return 0;
}
else {
printf("parent: %d left child: %d\n", getpid(), pid_l);
pid_r = waitpid(-1, &status, 0);
}
pid_r = fork();
if (pid_r == 0) { //right child
if(i == 0) { //first level
fprintf(file, " \"%d\" [ label=\"pid %d, level %d\" ];\n", getppid(), getppid(), i);
fprintf(file, " \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i + 1);
fprintf(file, " \"%d\" -> \"%d\";\n", getppid(), getpid());
}else{
fprintf(file, " \"%d\" [ label=\"pid %d, level %d\" ];\n", getpid(), getpid(), i + 1);
fprintf(file, " \"%d\" -> \"%d\";\n", getppid(), getpid());
}
}
else {
printf("parent: %d right child: %d\n", getpid(), pid_r);
pid_r = waitpid(-1, &status, 0);
break;
}
}
if (i == n) {
fprintf(file, "}");
fclose(file);
}
所以这里的方法 - 你需要fork
两次,立即从左边的孩子返回,继续作为新的父母在右边。
关于更改的更多说明:
- 你在所有的
fprintf()
电话中都有一个额外的论点。放弃最后一个file
论点。关于该主题有很多警告。 - 您没有正确填写点文件中的最后一个括号 - 替换
(i > n)
为i == n
通过使用重新设计的循环,输出看起来像这样:
这看起来更像你想要的。
推荐阅读
- postman - 使用文本分析 API 和 Postman 进行情绪分析
- html - 在 HTML 输入模式属性中转义“和”
- spring - 将 Spring Data JPA 与 Spring JPA 一起使用时的问题
- kotlin - kotlin 中 == 和 === 有什么区别
- perl - 在 Mojo 中查找以特定 url 开头的链接
- html - 全屏居中 html5 视频直播
- azure-devops - 如何限制对 VSTS 中特定工作项功能的访问
- javascript - 动作不触发reducer
- excel - VBA添加具有可变范围的小计
- menuitem - 错误:找不到函数“createRenderFunction”