c - 有没有办法更好地路由流程?
问题描述
我尝试使用 fork() 创建一个进程树,以便每个父级的子级数在给定数组中,例如,如果数组是 {2,1,3,0,0,0,0},则树看起来像这样:
| a |
/ \
| b | | c |
/ / | \
| d | | e | | f | | g |
通过检查从 fork() 返回的值是否为 0,我能够创建进程并将父进程与子进程分开。我设法创建了一个进程树,但我设法创建的树是对称的,而不是什么我真的很想建造。我无法弄清楚兄弟姐妹之间路由过程的部分,
如何分别检查每个进程应该为它创建多少个子进程,并为它创建而不为其他兄弟进程创建?
这是我到目前为止得到的:
int main() {
int nums[7] = { 2,1,3,0,0,0,0 };
int pid, pid2;
size_t len = sizeof(nums)/sizeof(int);
int childs2;
printf("\nProcess number %d has pid= %d\n", 0, getpid());
int childs = 1;
while( childs <= nums[0] ) {
pid = fork();
if (pid == 0 ) {
printf("Process number %d has pid= %d\n", childs, getpid());
printf("I am Process with pid=%d and my parent pid=%d\n", getpid(), getppid());
waitpid(getppid());
for (int i=1; i<len; i++) {
childs2 = 0;
if (childs2 < nums[i]) {
pid2 = fork();
if (pid2 == 0) {
printf("Process number %d has pid= %d\n", childs, getpid());
printf("I am Process with pid=%d and my parent pid=%d\n", getpid(), getppid());
waitpid(getppid());
break;
} else {
wait(NULL);
childs2++;
}
} else {
childs2++;
}
}
break;
} else {
wait(NULL);
childs++;
}
}
return 0;
}
我必须区分进程才能知道哪个进程是叶子,哪个进程是父进程。为此,我需要在每个过程中执行不同的操作,但我想不出办法,
我的输出是:
Process number 0 has pid= 98431
Process number 1 has pid= 98432
I am Process with pid=98432 and my parent pid=98431
Process number 1 has pid= 98433
I am Process with pid=98433 and my parent pid=98432
Process number 1 has pid= 98434
I am Process with pid=98434 and my parent pid=98432
Process number 2 has pid= 98435
I am Process with pid=98435 and my parent pid=98431
Process number 2 has pid= 98436
I am Process with pid=98436 and my parent pid=98435
Process number 2 has pid= 98437
I am Process with pid=98437 and my parent pid=98435
树看起来像:
| a |
/ \
| b | | c |
/ \ / \
| d | | e || f | | g |
但我希望输出为:
Process number 0 has pid= 98431
Process number 1 has pid= 98432
I am Process with pid=98432 and my parent pid=98431
Process number 2 has pid= 98433
I am Process with pid=98433 and my parent pid=98431
Process number 3 has pid= 98434
I am Process with pid=98434 and my parent pid=98432
Process number 4 has pid= 98435
I am Process with pid=98435 and my parent pid=98433
Process number 5 has pid= 98436
I am Process with pid=98436 and my parent pid=98433
Process number 6 has pid= 98437
I am Process with pid=98437 and my parent pid=98433
所以树看起来像:
| a |
/ \
| b | | c |
/ / | \
| d | | e | | f | | g |
.
解决方案
我们需要做的是跟踪我们在列表中的进程以及孩子在列表中的位置。以下代码显示了如何执行此操作。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NumberOf(a) (sizeof (a) / sizeof *(a))
/* Create children for process p.
In a child, return the number of that child process.
In the parent, return -1.
*/
static int CreateChildren(int NumberOfChildren[], int FirstChild[], int p)
{
// Create children for process p.
printf("Process %d has pid %u and parent %u.\n",
p, (unsigned) getpid(), (unsigned) getppid());
for (int i = 0; i < NumberOfChildren[p]; ++i)
{
pid_t pid = fork();
if (pid == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0)
/* This is a child process, and it is child i of process p, so
its process number is FirstChild[p] + i. Return that.
*/
return p = FirstChild[p] + i;
}
// Wait for children to finish.
for (int i = 0; i < NumberOfChildren[p]; ++i)
wait(0);
// Tell caller the parent finished.
return -1;
}
int main(void)
{
int NumberOfChildren[] = { 2, 1, 3, 0, 0, 0, 0 };
size_t N = NumberOf(NumberOfChildren);
// Check the NumberOfChildren array for consistency.
{
int sum = 0;
for (size_t n = 0; n < N; ++n)
{
if (NumberOfChildren[n] < 0)
{
fprintf(stderr,
"Error, number of children cannot be negative but is %d.\n",
NumberOfChildren[n]);
exit(EXIT_FAILURE);
}
sum += NumberOfChildren[n];
}
if (sum != N-1)
{
fprintf(stderr,
"Error, the numbers of children sum to %d desecendants "
"of the root, but array has %zu elements after the root "
"element.\n",
sum, N-1);
exit(EXIT_FAILURE);
}
}
/* Compile information about the children -- set FirstChild[n] to the
index of the element in NumberOfChildren that is for the first child
of process n.
*/
int FirstChild[N];
{
int NextChild = 1;
for (int n = 0; n < N; ++n)
{
FirstChild[n] = NextChild;
NextChild += NumberOfChildren[n];
}
}
// This is the root process. Set p to its index.
int p = 0;
/* Create children for process p. When a child is created, it will
return its process number, and we will loop to create children for it.
*/
while (p >= 0)
p = CreateChildren(NumberOfChildren, FirstChild, p);
}
样本输出:
进程 0 的 pid 为 2648,父进程为 2641。 进程 1 的 pid 为 2649,父进程为 2648。 进程 2 具有 pid 2650 和父进程 2648。 进程 3 的 pid 为 2651,父进程为 2649。 进程 4 具有 pid 2652 和父进程 2650。 进程 5 具有 pid 2653 和父进程 2650。 进程 6 具有 pid 2654 和父进程 2650。
推荐阅读
- kubernetes - 添加 jmx__javaagent 后无法在 kubernetes 中列出 kafka 主题
- javascript - React Redux 在一段时间不活动后更新(重新渲染)组件
- c++ - CUDA opencv 构建失败 - 缺少实际存在的文件
- gremlin - 查询 repeat().until() 的功能
- elasticsearch - 如何从头开始划分 ElasticSearch 查询
- php - 仅使用数组中的字符串 3 次,然后继续下一个
- namespaces - 命名空间会影响每个实体组每次写入 1 秒的时间吗?
- google-maps - 3.34版本更新后谷歌地图控制按钮太大
- php - 从一页到下一页的 PHP 值
- angular - Angular - angular6 中 web 工作者的 webpack 配置