简体   繁体   English

了解Unix中的fork机制

[英]Understanding fork mechanism in Unix

I am trying to figure out the behaviour of parent and child process. 我试图弄清楚父子进程的行为。 Below is my code 下面是我的代码

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

int main(void)
{
    int i,j,cnt=0;
    int pid,present_pid;
    int a[10];
    for(i=0; i<10; i++) {
        a[i] = i;
    }

    i = 0;
    j = 5;
    present_pid = getpid();
    printf("Now in process %d\n",getpid());
    printf("\n*******************before fork******************\n");
    for(i=0;i<10;i++) {
        printf("  %d",a[i]);
    }
    printf("\n*******************before fork******************\n");

    int ret = fork();
    if(ret == 0) {
        printf("\n*******************after fork******************\n");
        printf("Now in process %d\n",getpid());
        printf("Child Process created");
        for(i=0; i<5; i++) {
            a[i]= +1;
            i++;
        }
    }
    else if(ret > 0) {
        printf("\nNow in process %d\n",getpid());
        for(j=5; j<10; j++) {
            a[j] = +1;
            j++;
        }
        wait();
    }

    for(i=0;i<10;i++) {
        printf("  %d",a[i]);
    }
    return 0;
}

This is the output of the program 这是程序的输出

Now in process 12248

*******************before fork******************
  0  1  2  3  4  5  6  7  8  9
*******************before fork******************

*******************after fork******************
Now in process 12249
Child Process created  1  1  3  3  5  5  6  7  8  9
Now in process 12248
  0  1  2  3  4  6  6  8  8 

So Initially there is only one process 12248 which forks another process (12249). 因此,最初只有一个进程12248分叉另一个进程(12249)。 Now both the process run parallel (please correct me if I am wrong). 现在,两个过程并行运行(如果我错了,请纠正我)。 Ideally child should add 1 to the contents of array a only to the first half and parent should do the same of the second part. 理想情况下,child应该仅将数组a的内容加1到前半部分,parent应该对第二部分做相同的操作。 But as you can see the output is not as expected. 但是,您可以看到输出与预期的不同。 Please give suggestions.. 请提出建议。

A process created by fork is a real heavyweight OS process, not only a lightweight thread! fork创建的进程是真正的重量级OS进程,不仅是轻量级线程! The created process does not share any memory with the process from which it was forked. 创建的进程不与派生该进程的进程共享任何内存。 Instead, the memory is copied (lazily, so-called copy-on-write), so you actually have two arrays a now and each process writes to his own copy of a . 相反,在复制内存(懒洋洋地,所谓的写入时复制),所以你实际上有两个数组a现在,每个进程写自己的副本a

there are 2 small mistake in your code. 您的代码中有2个小错误。 Usually we don't even notice their existence. 通常我们甚至都不注意到它们的存在。

  1. a[i]= +1; oh, dear. 噢亲爱的。 I guess you want to write a[i] += 1 or a[i]++ . 我猜你想写a[i] += 1a[i]++
  2. Redundant i++ and j++ . 冗余i++j++ The for loop has done this for you. for循环已为您完成了此任务。

Correct them, and you'll get your expected answer. 纠正它们,您将得到预期的答案。

First of all make some changes to your code 首先对您的代码进行一些更改

 printf("Now in process %d\n",getpid());
        printf("Child Process created");
        for(i=0; i<5; i++)
         {
   -->         a[i]+= 1;
    -->     //   i++; //comment this line you are jumping 2 steps in this loop
         }

As for the concept of fork() 至于fork()的概念

Whenever you do a fork() call the exact copy of the process address space is created for child process and the program counter is set to the line after the fork() call 每当您执行fork()调用时,都会为子进程创建进程地址空间的确切副本,并且将程序计数器设置为fork()调用之后的行

In your case after this line 您在此行之后的情况

     int ret = fork();
Program Counter-->    if(ret == 0)
                           {

next, 下一个,

Now both the process run parallel

Yes the parent process does run in parallel but it waits for SIGCHLD signal from child process after its execution is finished. 是的,父进程确实可以并行运行,但是它在执行完成后会等待子进程的SIGCHLD信号。

If the child process returns the SIGCHLD signal but the parent process didn't recieve it yet(ie the parent process is in wait state) then the child process is called ZOMBIE process. 如果子进程返回SIGCHLD信号,但父进程尚未接收到该信号(即,父进程处于等待状态),则子进程称为ZOMBIE进程。

IF the parent process aborts abruptly and the child process is still running(or in READY state) the child process is called ORPHAN process. 如果父进程突然中止并且子进程仍在运行(或处于READY状态),则该子进程称为ORPHAN进程。 In this case the process called init is responsible for collecting the status of child process. 在这种情况下,称为init的进程负责收集子进程的状态。

finally, the program flow. 最后,程序流程。 The parent process runs initially. 父进程最初运行。

int ret = fork();//A child process is created

then this code executes in the child process 然后这段代码在子进程中执行

        if(ret == 0)
      {
        printf("\n*******************after fork******************\n");
        printf("Now in process %d\n",getpid());
        printf("Child Process created");
        for(i=0; i<5; i++)
         {
            a[i] += 1;
            //i++;
         }
      }
       else if(ret > 0)//this condition is false in child process
      {
          // rest of code
      }

//and finally this is exceuted //最后这被执行

for(i=0;i<10;i++)
  {
    printf("  %d",a[i]);
  }
return 0;
    then child process returns SIGCHLD signal

the following code is executed in parent process 在父进程中执行以下代码

        else if(ret > 0)//this is true for parent process
      {
        printf("\nNow in process %d\n",getpid());
        for(j=5; j<10; j++)
          {
            a[j] = +1;
            j++;
          }
        wait();
      }

    for(i=0;i<10;i++)
      {
        printf("  %d",a[i]);
      }
    return 0;

} }

NOTE: The parent process also returns the SIGCHLD signal and this signal is collected by init process 注意:父进程还返回SIGCHLD信号,此信号由init进程收集

Whenever a new process is spawn it is by default child process of init process 每次产生新进程时,默认情况下它都是init进程的子进程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM