Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用Fork()创建所需数量的进程_C - Fatal编程技术网

C 使用Fork()创建所需数量的进程

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

我正试图了解系统调用fork(),我想创建尽可能多的孙进程。基本上,我想要实现的是:

1个父进程->2个子进程->每个子进程->有两个子进程(来自父进程的总共4个子进程)

到目前为止,我能从四个孙子中得到三个,但我也从一个孙子那里得到了一个新的孩子。这是到目前为止我得到的输出:

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;
}