我正在学习fork如何在类Unix操作系统中工作。我想创建9个子进程,每个父进程只能创建2个子进程。所以这是一个二进制fork算法。
然而,我不能设法限制在第三次递归调用中创建的孩子的正确数量。
下面是创建子节点的流程。
这是我现在拥有的代码。
#include <iostream.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
static int CHILD_SIZE = 9;
static int LEVEL = 1;
static int MAX_LEVEL = 3;
void createChildren(int remaining, int level) {
int CURRENT_REMAINING = remaining;
if(CURRENT_REMAINING <= 0 || level > MAX_LEVEL){
return;
}
pid_t firstChild,secondChild;
// Fork the first child
firstChild = fork();
if(firstChild == -1){
cerr << "Fork failed!" << endl;
}
else if (firstChild == 0 && CURRENT_REMAINING > 1)
{
// first child
cout << "First child process (PID: " << getpid() << ") with parent process (PID: " << getppid() << ") at level: " << level << endl;
// calculate how many child needs after this iteration
CURRENT_REMAINING -= (2 * level);
if(CURRENT_REMAINING < 0){
CURRENT_REMAINING = 0;
}
}
else if (firstChild > 0 && CURRENT_REMAINING > 1)
{
// Fork the second child
secondChild = fork();
if(firstChild == -1){
cerr << "Fork failed!" << endl;
}
else if (secondChild == 0) {
// second child
waitpid(firstChild, NULL, 0);
cout << "Second child process (PID: " << getpid() << ") with parent process (PID: " << getppid() << ") at level: " << level << endl;
// calculate how many child needs after this iteration
CURRENT_REMAINING -= (2 * level);
if(CURRENT_REMAINING < 0){
CURRENT_REMAINING = 0;
}
} else if (secondChild > 0){
// Wait for both child processes to complete
waitpid(firstChild, NULL, 0);
waitpid(secondChild, NULL, 0);
}
}
//---------- recursion call-----------//
// upper child recursion call
if(firstChild == 0){
cout << "current remaining in first child is: " << CURRENT_REMAINING << " at level " << level << endl;
createChildren(CURRENT_REMAINING, level + 1);
}
// lower child recursion call
if(secondChild == 0){
cout << "current remaining in second child is: " << CURRENT_REMAINING << " at level " << level << endl;
if(CURRENT_REMAINING > 3){
//cout << "Create two more processes" << endl;
createChildren(CURRENT_REMAINING, level + 1);
}
}
}
int main() {
std::cout << "Parent process " << getpid() << std::endl;
createChildren(CHILD_SIZE, LEVEL);
return 0;
}
字符串
下面是输出:
Parent process 8571
First child process (PID: 8573) with parent process (PID: 8571) at level: 1
current remaining in first child is: 7 at level 1
Second child process (PID: 8574) with parent process (PID: 8571) at level: 1
current remaining in second child is: 7 at level 1
First child process (PID: 8575) with parent process (PID: 8573) at level: 2
current remaining in first child is: 3 at level 2
First child process (PID: 8576) with parent process (PID: 8574) at level: 2
current remaining in first child is: 3 at level 2
Second child process (PID: 8577) with parent process (PID: 8573) at level: 2
current remaining in second child is: 3 at level 2
Second child process (PID: 8578) with parent process (PID: 8574) at level: 2
current remaining in second child is: 3 at level 2
First child process (PID: 8579) with parent process (PID: 8575) at level: 3
current remaining in first child is: 0 at level 3
Second child process (PID: 8581) with parent process (PID: 8575) at level: 3
current remaining in second child is: 0 at level 3
First child process (PID: 8580) with parent process (PID: 8576) at level: 3
current remaining in first child is: 0 at level 3
Second child process (PID: 8582) with parent process (PID: 8576) at level: 3
current remaining in second child is: 0 at level 3
型
第一个调用生成2个子元素,第二个调用生成4个子元素,第三个调用生成4个子元素,但应该是3个。
1条答案
按热度按时间osh3o9ms1#
你希望每个进程最多执行两次
fork()
,所以你不需要任何循环、递归之类的东西。给定一个命令行参数
9
,下面的程序will print 10倍Terminating.
和9倍Waited for: <pid>
,这似乎是你的绘图指定的。字符串
只要有两个无约束的
fork()
,它就相当于Bash的强大功能:型
为了驯服进程数量的指数增长,我们限制了一个进程在
fork()
ing树上运行fork()
的次数,如果我们希望fork()
s的总数保持不变,这个数量需要指数下降。剩下的就是正确处理细节了。第一个子树被授予
fork()
s的remaining / 2 + remaining % 2
,第二个子树获得其余的。这可以正确处理奇数和偶数情况。此外,除了原始(grand)父进程之外的所有进程也必须计数 * 自身 *,这就是为什么它们总是以--remaining
开始。由于the
goto
的原因,在这段代码中使用RAII在可读性方面是有争议的。我几乎可以肯定有一种方法可以实现它而不需要向后跳转的goto
语句,但我也懒得去想这个问题。