1

出力が印刷される順序を理解できません...

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

int main(void)
{
    int index;
    for (index = 1; index < 4; index++)
    {
        printf("HI\n"); 
        fork();
    }
    printf("Unix System Programming\n");
    exit(0);
}

UNIXプログラミングシステムのみを印刷すると、フォークが2 ^ n回機能することを理解するのは簡単です...しかし、HIを印刷すると...なぜこのシーケンスが理解できませんか? 出力:

HI
HI
HI
HI
HI
Unix System Programming
HI
HI
Unix System Programming
Unix System Programming
Unix System Programming
Unix System Programming
Unix System Programming
Unix System Programming
Unix System Programming
4

3 に答える 3

2

視認性を高めるために、コードを変更しました

int main(void)   
    {  
        int index;  
        for (index = 1; index < 4; index++)  
        {
            printf("We are in loop with  process id=%d\n",getpid());
            if(!fork()) { //Child process
               printf("Came inside chid with process id=%d\n",getpid());
              // _exit(0);
            } else {     //Parent process
              printf("Came inside parent with process id=%d\n",getpid());
           }
        }
        printf("We are out of loop with  process id=%d\n",getpid());
        exit(0);
    }

    [OP]   
    We are in loop with  process id=2258   -----> Main Parent   
    Came inside parent with process id=2258   
    We are in loop with  process id=2258  
    Came inside child with process id=2259  
    We are in loop with  process id=2259  
    Came inside parent with process id=2258  
    We are in loop with  process id=2258  
    Came inside parent with process id=2259  
    We are in loop with  process id=2259  
    Came inside parent with process id=2258  
    We are out of loop with  process id=2258 ----> "Outer block of loop referring main Parent  Here exit(0) will rip parent process of pid 2258 "      
    Came inside parent with process id=2259     
    We are out of loop with  process id=2259   
    Came inside child with process id=2263   
    We are out of loop with  process id=2263   
    Came inside child with process id=2261   
    We are in loop with  process id=2261   
    Came inside parent with process id=2261   
    We are out of loop with  process id=2261   
    Came inside child with process id=2264   
    We are out of loop with  process id=2264   
    Came inside child with process id=2262   
    Came inside child with process id=2260   
    We are out of loop with  process id=2262   
    We are in loop with  process id=2260   
    Came inside parent with process id=2260   
    We are out of loop with  process id=2260   
    Came inside child with process id=2265   
    We are out of loop with  process id=2265   

最初に、fork が 1 つの子を生成するたびに 3 回実行されるループを検討する必要があります。このループには確実に 1 つの親があり、実行はスケジューリングに完全に依存し、子または親になる可能性があります。

反復値が増えると、これを理解するのが本当に頭を悩ませることになります。

今、子供をきれいにしましょう

    int main(void)   
            {  
                int index;  
                for (index = 1; index < 4; index++)  
                {
                    printf("We are in loop with  process id=%d\n",getpid());
                    if(!fork()) { //Child process
                       printf("Came inside chid with process id=%d\n",getpid());
                       _exit(0);
                    } else {     //Parent process
                      printf("Came inside parent with process id=%d\n",getpid());
                   }
                }
                printf("We are out of loop with  process id=%d\n",getpid());
                exit(0);
            }

    We are in loop with  process id=2393
Came inside parent with process id=2393
We are in loop with  process id=2393
Came inside chid with process id=2394
Came inside parent with process id=2393
We are in loop with  process id=2393
Came inside parent with process id=2393
We are out of loop with  process id=2393
Came inside chid with process id=2396
Came inside chid with process id=2395

したがって、上記の OP はより明確になり、親の実行が 3 回、子の実行が 3 回になりました。

于 2013-03-02T13:51:02.770 に答える
1

コンピュータがプロセスをスケジュールするためにどの順序を選択するかについて保証はありません。あるプロセスが完全に実行されてから、別のプロセスが 1 行実行されることがあります。

出力の考えられる説明の 1 つ:

列はプロセス、インデックスは括弧内

「USP」は「Unix System Programming」です。
「FORK」はプロセスがフォークするとき
です。「CREATE」はプロセスが作成されるときです。

1      2      3      4      5      6      7      8
HI (1)
FORK   CREATE
HI (2)
FORK          CREATE
       HI (2)
       FORK          CREATE
HI (3)
FORK                        CREATE
                     HI (3)
                     FORK          CREATE
USP
              HI (3)
              FORK                        CREATE
       HI (3)
       FORK                                      CREATE
       USP
              USP
                     USP
                            USP
                                   USP
                                          USP
                                                 USP

コンピューターがプロセスをスケジュールする順序がわからないため、上記が実際の出力である可能性は低いです。プロセス ID を print ステートメントに追加して、出力の特定の行がどのプロセスに属しているかを示すことができます。

于 2013-03-02T11:47:34.647 に答える
0

各プロセスの PID を照会することで、何が起こっているかのより詳細なビューを取得できます。

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

int main(void)
{
    int index;
    for (index = 1; index < 4; index++)
    {
        printf("HI: pid %d with i=%d will now fork\n", getpid(), index);
        if (0 == fork())
        {
                printf("I am a new process with i=%d and pid=%d\n", index, getpid());
        }
    }
    printf("Unix System Programming from pid %d\n", getpid());
    exit(0);
}

printf() のシーケンスに関しては、実際には、生成される新しいプロセスが完全に生成される前にランダムな時間がかかり (小さい、ほとんどゼロですが、それでもランダムです)、その時間は、親がさらにプロセスを生成して終了するのに必要な時間。

したがって、次のことが考えられます。

process 1 prints "HI" and spawns process 2
process 2 prints "HI" and...
process 1 prints "HI" and spawns process 3
                             ... spawns process 4
...process 2 terminates ("Unix programming")
...process 3 terminates ("Unix programming")
...process 4 prints "HI"

次回は、プロセス 3 が生成される前に、プロセス 2 が HI の出力に成功する可能性があります。決定論的なシーケンスが必要な場合は、ある種のプロセス同期を実装する必要があります。

于 2013-03-02T11:50:49.190 に答える