如何使用fork()创建确切数量的子进程

4
我正在开发一个会多次执行特定任务的程序。我已经使用线程编写了该程序,但现在需要使用fork()来实现。
使用线程时,我只需创建指定数量的线程,让它们执行函数(更改共享内存中的变量),然后最终执行使用共享内存中的最终值的某些操作。
现在,我想做同样的事情,但不确定如何做到这一点,因为每次调用fork()时,它本质上都会成倍增加。所以,如果我在for循环中调用fork(),则每个父进程和子进程都将通过循环,在自己身上调用fork()。
简而言之,我的问题是: 如何使用fork创建精确数量的子进程(假设我需要5个子进程),并使父进程等待这些5个子进程执行完毕后再继续执行?
感谢您的帮助!

每个孩子都知道它是孩子;确保它只做一个孩子应该做的事情(去上学?),并确保它在父进程执行的位置退出而不是继续执行(在工作中?)。就像 niculare 或 Quentin 的答案一样。 - Jonathan Leffler
2个回答

8
我认为这个方案可行:
int processes = 5;
int i;
for (i = 0; i < processes; ++i) {
    if (fork() == 0) {
        // do the job specific to the child process
        ...
        // don't forget to exit from the child
        exit(0);
    }
}
// wait all child processes
int status;
for (i = 0; i < processes; ++i)
    wait(&status);

1
这个代码是有效的,但你需要调用waitpid函数5次而不是一次。waitpid(-1)表示等待“任何”子进程退出,而不仅仅是一个。 - selbie
这难道不意味着每个子进程都将继续循环吗?例如,当i为0时,您会生成一个子进程,现在子进程父进程都有循环并且都增加i,两者都fork一个新的子进程,现在您有4个进程,所有进程都增加i...等等。也许我错了,需要喝咖啡... - dreamlax
@dreamlax fork() 在子进程中返回0,在父进程中返回子进程的pid。检查 if (fork() == 0) 确保 if 块中的代码只会被子进程执行。由于 if 块中没有 fork(),因此子进程不会创建更多进程。 - niculare
@niculare:现在加上了exit(0),这就有了很大的区别!没有它,子进程将会像父进程一样继续循环。 - dreamlax

1

你可以将进程结构化,使每个进程分叉出相应数量的子进程(例如,父进程分叉n次,子进程分叉n-1次,它们的子进程分叉n-2次等),或者限制分叉只有父进程继续循环(这将是最简单的情况)。因此让子进程退出循环。


如果子进程退出循环,这意味着最终我们没有任何活动的子进程? - Wokers
不,子进程会退出fork()循环,但是继续正常执行。父进程会在循环中创建更多的子进程,并最终退出循环。 - hdante

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接