要分叉X进程并让父进程等待,我有以下代码:
int maxProcesses = 10;
for (int currentChild = 0; currentChild < maxProcesses; currentChild++) {
pid_t pid = fork();
if (pid < 0) {
// Error
} else if (pid == 0) {
// Child
} else {
// Parent
// Should I call waitpid on pid and wait here instead?
}
}
// Wait for all children
for (int currentChild = 0; currentChild < maxProcesses; currentChild++) {
wait(NULL);
}
现在我想修改代码,以便在X总进程中,Y首先分叉,然后当它们完成时,会产生更多的分叉,直到达到所需的总数。我已经对上面的代码进行了一些更改,并提出了一些问题。
int totalProcessesToBeForked = 10;
int maxAllowedAtOnce = 5;
for (int currentChild = 0; currentChild < maxAllowedAtOnce; currentChild++) {
forkChild(currentChild);
}
// Wait for all children
// # How do I modify this to wait for new children forked as well
// # if I move it inside parent, it will make things easier, right?
for (int currentChild = 0; currentChild < maxAllowedAtOnce; currentChild++) {
wait(NULL);
}
void forkChild(currentChild) {
pid_t pid = fork();
if (pid < 0) {
// Error
} else if (pid == 0) {
// Child
} else {
// Parent
// # I think waiting here using waitpid will be better b/c
// # as new forks are made, parent begins to wait for them
}
}
我可能需要计算已分叉的子项数并将其与totalProcessesToBeForked进行比较,并相应地分叉新的子项。
更新了代码v1:
int maxProcesses = 10;
int maxAllowedAtOnce = 5;
int main(int argc, char* argv[]) {
// Start timer
alarm(10); // Terminate after 10s
signal(SIGALRM, onTimeout);
signal(SIGCHLD, catchChild);
for (int currentChild = 0; currentChild < maxAllowedAtOnce; currentChild++) {
forkChild(currentChild);
}
// # This sections runs immediately before death of any child is reported
// # and starts cleanup processes, thus killing any/all running children
// Completed before timeout
endTimer = true;
int timeRemaining = alarm(0);
if (timeRemaining > 0) {
printf("\nCompleted w/ %is remaining. Performing cleanup.\n", timeRemaining);
// Kill children any running child processes, cleanup
cleanup();
}
return 0;
}
void forkChild(currentChild) {
pid_t pid = fork();
if (pid < 0) {
// Error
} else if (pid == 0) {
// Child
execl("/bin/date", "date", 0, 0);
} else {
// Parent
printf("#Log: Started %i.\n", currentChild + 1);
}
}
void catchChild(int sig) {
pid_t p;
int state;
p=wait(&state);
printf("Got child %d\n",p);
}
void cleanup() {
// Cleanup Code
}
示例运行:
编辑#2: http://ideone.com/noUs3m
答案 0 :(得分:1)
不要像你一样使用wait
,而是想要查看信号处理来处理死亡的子进程。
在开始fork
之前添加,此行
signal(SIGCHLD,catchchild);
这个函数代码
void catchchild(int sig)
{
pid_t p;
int state;
p=wait(&state);
printf("Got child %d\n",p);
}
然后,只要子进程终止,您的主进程就会调用catchchild
。
正如您已经解决的那样,如果您计算了分叉的子女数量,您可以catchchild
更新,以便您的主要代码知道fork
一个新的孩子。
回答您的评论,如下所示,除了更多错误检查
while(totalProcessesToBeForked)
{
if(currentChild < maxAllowedAtOnce)
{
forkChild(currentChild);
totalProcessesToBeForked--;
}
sleep(1);
}