C 使用Fork()创建所需数量的进程
我正试图了解系统调用fork(),我想创建尽可能多的孙进程。基本上,我想要实现的是: 1个父进程->2个子进程->每个子进程->有两个子进程(来自父进程的总共4个子进程) 到目前为止,我能从四个孙子中得到三个,但我也从一个孙子那里得到了一个新的孩子。这是到目前为止我得到的输出:C 使用Fork()创建所需数量的进程,c,C,我正试图了解系统调用fork(),我想创建尽可能多的孙进程。基本上,我想要实现的是: 1个父进程->2个子进程->每个子进程->有两个子进程(来自父进程的总共4个子进程) 到目前为止,我能从四个孙子中得到三个,但我也从一个孙子那里得到了一个新的孩子。这是到目前为止我得到的输出: Process Pid: 5960 PPid: 5958 (position: 1). Process Pid: 5959 PPid: 5958 (position: 0). Process Pid: 5962 PPid
Process Pid: 5960 PPid: 5958 (position: 1).
Process Pid: 5959 PPid: 5958 (position: 0).
Process Pid: 5962 PPid: 5959 (position: 0).
Process Pid: 5961 PPid: 5960 (position: 1).
Process Pid: 5963 PPid: 5961 (position: 1).
Process Pid: 5964 PPid: 5960 (position: 1).
有什么建议吗
多谢各位
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#define NUM_HIJOS 2
void lanzanieto(int i)
{
int proceso;
proceso = fork();
if (proceso > 0) {
wait(NULL);
} else if (proceso == 0) {
printf("Process Pid: %d PPid: %d (position: %d).\n",getpid(),getppid(), i);
} else if (proceso == -1) {
perror("fallo en fork");
exit(EXIT_FAILURE);
}
}
int main(void)
{
int proceso, i;
for (i=0; i<NUM_HIJOS; i++) {
proceso = fork();
if (proceso == 0) {
switch(i) {
case 0:
printf("Process Pid: %d PPid: %d (position: %d).\n",getpid(),getppid(), i);
lanzanieto(i);
exit(0);
case 1:
printf("Process Pid: %d PPid: %d (position: %d).\n",getpid(),getppid(), i);
lanzanieto(i);
lanzanieto(i);
exit(0);
}
} else if (proceso == -1) {
perror("fallo en fork");
exit(EXIT_FAILURE);
}
}
proceso = wait(NULL);
while (proceso > 0) {
proceso = wait(NULL);
}
/* ************************************* */
if (proceso == -1 && errno != ECHILD) {
perror("fallo en wait");
exit(EXIT_FAILURE);
}
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义NUM_HIJOS 2
void lanzanieto(国际一级)
{
int proceso;
proceso=fork();
如果(过程>0){
等待(空);
}else if(proceso==0){
printf(“进程Pid:%d PPid:%d(位置:%d)。\n”、getpid()、getppid()、i);
}else if(proceso==-1){
佩罗尔(“法伦福克”);
退出(退出失败);
}
}
内部主(空)
{
int proceso,i;
对于(i=0;i=0){
proceso=wait(空);
}
/* ************************************* */
if(proceso==-1&&errno!=ECHILD){
佩罗尔(“法洛等待”);
退出(退出失败);
}
}
概念
首先,创建一个fork()
如下所示:
id = fork();
if (id < 0) {
/* error */
exit(1);
}
else if (i > 0) { /* Parent > 0 */
/* parent logic */
}
else { /* Child = 0 */
/* child logic */
}
简单地说,您必须在父进程和每个新的子进程中递归地fork()
然而,要承认这样的分叉过程并不好看
最好有一个函数,比如说create_child()
,它只从父级分叉:
parent : create_fork()
|--> parent : create_child()
| |
| |--> parent : create_child()
| | |
| | |--> parent
| | |--> child_3 : do_whatever()
| |
| |--> child_2 : do_whatever()
|
|--> child_1 : do_whatever()
解决方案
#包括
#包括
#包括
#包括
#包括
无效打印pid(字符*程序名称)
{
printf(“%s:%d\n”,进程名,getpid());
}
int创建子对象(空)
{
pid_t child_pid=fork();
如果(子项pid==0)
{
打印pid(“子项”);
}
else if(子项pid<0)
{
perror(“创建孩子”);
}
返回(child_-pid);
}
int制造婴儿(int婴儿编号)
{
/*如果没有孩子*/
如果(婴儿数量0)
{
制作婴儿(婴儿编号-1);
waitpid(child_pid,NULL,0);
}
返回子对象;
}
内部主(空)
{
打印pid(“父项”);
生孩子(50);
返回errno;
}
您必须记住,子进程和父进程都继续执行相同的代码。当您在案例1:main()
中两次调用lanzanieto(i)
时,第一次调用lanzanieto(i)
的父级和子级(即原始父级的子级和孙子级)继续第二次调用lanzanieto(i)
,因此,两者都会产生另一个子项。您是如何识别流程层次结构树的?请发布输出。我还没有,我仍在试图找出如何先完成所有4个孙子。一旦我得到它,我会去与职位Id号。张贴的代码逻辑是不正确的,你正试图执行。强烈建议修改代码以“直接”了解它想要做什么,而不是使用循环计数器、对exit()
的各种调用和对lanzanieto()的各种调用。最后,“direct”方法的效果会更好。发布的代码使用“int”作为从fork()返回的类型,但是它实际上返回了一个“pid\t”。注意:“pid_t”是在unistd.h中定义的。谢谢你的评论,但你的建议是我正在做的,而不是“如果”,我使用一个开关和一个函数来启动childs(lanzanieto(I))。我添加了解决方案。谢谢你,Valentin,我遵循了你的建议,我这样做了。你可以在另一个帖子中看到最终的结果,我带着新的疑问打开了这个帖子。如果它符合你的需要,它就可以了。考虑验证这个解决方案,以便结束这个问题。谢谢。我明白你的意思,但你建议我如何终止那个额外的进程?@krm76你不会终止它;您必须确保不创建它。在lanzanieto()
中,通过fork
的返回值,您可以知道自己是家长还是孩子,因此您可以决定做什么。(在main
中,我看到您在子对象中使用exit(0)
,以避免继续--您可以在lanzanieto()
中执行类似的操作。
parent : fork()
|--> parent : fork()
| |--> parent
| |--> child_2
|
|--> child_1 : fork()
|--> child_1
|--> sub_child_1
parent : create_fork()
|--> parent : create_child()
| |
| |--> parent : create_child()
| | |
| | |--> parent
| | |--> child_3 : do_whatever()
| |
| |--> child_2 : do_whatever()
|
|--> child_1 : do_whatever()
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
void print_pid(char *proc_name)
{
printf("%s: %d\n", proc_name, getpid());
}
int create_child(void)
{
pid_t child_pid = fork();
if (child_pid == 0)
{
print_pid("child");
}
else if (child_pid < 0)
{
perror("create_child");
}
return (child_pid);
}
int make_babies(int babies_number)
{
/* if no baby */
if (babies_number <= 0)
return 0;
/* if baby(ies) */
pid_t child_pid = create_child();
if (child_pid > 0)
{
make_babies(babies_number - 1);
waitpid(child_pid, NULL, 0);
}
return child_pid;
}
int main(void)
{
print_pid("parent");
make_babies(50);
return errno;
}