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 

したがって、最初は、別のプロセス (12249) をフォークするプロセス 12248 が 1 つしかありません。これで、両方のプロセスが並行して実行されます (間違っている場合は修正してください)。理想的には、子は配列aの内容に前半のみに1 を追加し、親は 2 番目の部分に同じことを行う必要があります。しかし、ご覧のとおり、出力は期待どおりではありません。提案をしてください..

4

3 に答える 3

3

によって作成されたプロセスforkは、単なる軽量スレッドではなく、真の重量 OS プロセスです! 作成されたプロセスは、フォーク元のプロセスとメモリを共有しません。代わりに、メモリがコピーされます (レイジー、いわゆるコピー オン ライト)。そのため、実際には 2 つの配列aがあり、各プロセスは の独自のコピーに書き込みますa

于 2012-10-18T10:52:58.917 に答える
1

コードに2つの小さな間違いがあります。通常、私たちはそれらの存在にさえ気づきません。

  1. a[i]= +1;まあ。私はあなたが書きたいと思いますa[i] += 1a[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 に答える