0

我试图弄清楚父进程和子进程的行为。下面是我的代码

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

这是程序的输出

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 

因此,最初只有一个进程 12248 派生出另一个进程(12249)。现在这两个过程并行运行(如果我错了,请纠正我)。理想情况下,孩子应该只在前半部分的数组a的内容中添加 1 ,而父母应该对第二部分做同样的事情。但是正如您所看到的,输出并不像预期的那样。请给建议..

4

3 回答 3

3

创建的进程fork是真正的重量级 OS 进程,而不仅仅是轻量级线程!创建的进程不与派生它的进程共享任何内存。相反,内存被复制(懒惰地,所谓的写时复制),所以你a现在实际上有两个数组,每个进程都写入他自己的a.

于 2012-10-18T10:52:58.917 回答
1

您的代码中有两个小错误。通常我们甚至不会注意到它们的存在。

  1. a[i]= +1;哦亲爱的。我猜你想写a[i] += 1or a[i]++
  2. 冗余i++j++for循环已为您完成此操作。

纠正他们,你会得到你预期的答案。

于 2012-10-18T11:13:11.157 回答
0

首先对您的代码进行一些更改

 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
         }

至于fork()的概念

每当您执行 fork() 调用时,都会为子进程创建进程地址空间的精确副本,并且程序计数器设置为 fork() 调用之后的行

在您的情况下,在此行之后

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

下一个,

Now both the process run parallel

是的,父进程确实并行运行,但它在执行完成后等待SIGCHLD来自子进程的信号。

如果子进程返回 SIGCHLD 信号但父进程还没有收到(即父进程处于等待状态),则子进程称为ZOMBIE进程。

如果父进程突然中止并且子进程仍在运行(或处于READY状态),则子进程称为ORPHAN进程。在这种情况下,被调用的进程init负责收集子进程的状态。

最后,程序流程。父进程最初运行。

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

然后这段代码在子进程中执行

        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
      }

//最后这被执行了

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

以下代码在父进程中执行

        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;

}

注意:父进程也返回 SIGCHLD 信号,该信号由init进程收集

每当产生一个新进程时,它默认是进程的子init进程

于 2012-10-18T11:34:43.970 回答