父进程未终止

时间:2018-02-11 04:04:16

标签: c fork

我有一个父和子进程都计数到50,然后终止。父进程等待,直到子进程计数到50,然后退出。我已经编写了代码,但它将进入无限循环:

int main()
{
   long int T_Child = 0, T_parent = 0;
   pid_t procid = fork();
   int T = 0;
   if(procid < 0)
   {
       printf("\nFailed");
       exit(0);
   }
   else if(procid == 0)
   {//child
        while(T_Child < 50)
        {
            printf("\nCHILD : %ld",T_Child);
            delay(2);
            T_Child++;
        }  
        exit(1);
   }
   else if(procid > 0)
   {//parent
       while(T_parent < 50)
       {
           printf("\nPARENT : %ld",T_parent);
           delay(2);
           T_parent++;
       }
       while(T_Child < 50)
       {//to ensure parent exits after child
           delay(1);
       }
       exit(1);
  }
  return 0;
 }

我是这个领域的新手。请帮忙!

2 个答案:

答案 0 :(得分:2)

分叉与线程不同。 fork创建进程的副本。该 子进程中变量的值与 fork() 时父进程的变量。这意味着 子变量从父级继承值,但是更改了 父级无法看到子变量。

如果父母需要等待孩子退出,则必须致电 wait or waitpid。此外,如果父母需要从孩子,父母和孩子那里获得价值 应该相互通信,例如使用pipe

以下代码显示了parant和child如何相互通信和 父母应如何等待孩子离开:

#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void)
{
    int comm[2];

    // create pipe

    if(pipe(comm) < 0)
    {
        perror("Could not create pipe");
        return 1;
    }

    pid_t pid = fork();

    if(pid < 0)
    {
        perror("Could not fork");
        close(comm[0]);
        close(comm[1]);
        return 1;
    }

    if(pid == 0)
    {
        // CHILD

        // closing reading end of the pipe
        close(comm[0]);

        do_some_work();

        int result = 50;

        // write to the parant through the pipe
        write(comm[1], &result, sizeof result);

        // closing writing end
        close(comm[1]);

        exit(0);
    }

    // PARENT

    // close writing end of pipe
    close(comm[1]);

    puts("Now waiting for the child to exit...");

    // parent waits for child to exit
    int child_status;
    if(waitpid(pid, &child_status, 0) < 0)
    {
        perror("Could not wait");
        close(comm[0]);
        return 1;
    }

    // if child exited without any error
    if(WIFEXITED(child_status) && WEXITSTATUS(child_status) == 0)
    {
        // read answer from the child
        int answer;
        read(comm[0], &answer, sizeof answer);

        printf("Child answered with %d\n", answered);
    }

    // closing reading end of pipe
    close(comm[0]);
    return 0;
}

答案 1 :(得分:2)

子进程和父进程在不同的内存空间中运行。在fork()时,两个内存空间都具有相同的内容。

有一个名为写入时复制(CoW)的概念;了解它有用 -

  

Copy on Write是一种优化,其中设置了页表,以便父进程和子进程开始共享所有相同的内存,并且只有在需要时才复制任一进程写入的页面。

[上面是从我自己的答案复制到旧帖子中]

在你正在执行的程序中:

   while(T_Child < 50)
   {//to ensure parent exits after child
       delay(1);
   }

T_Child0之前使用fork初始化T_Child。由于地址空间是分开的,当子进程修改T_Child的值时,CoW会创建其页面的副本 - 但0的父副本仍具有初始值T_Child。父进程未对while中的值进行任何更改。因此,T_Child < 50循环条件while(T_Child < 50){..将始终为真,循环将无限执行。

相反,您应该等待子进程使用waitpid系统调用退出。代替waitpid(procid,&status,0); 循环,你应该这样做:

accounts

这将使父进程等到子进程退出。