7

私の質問は次のとおりです。

1.) 親プロセスを常に最後に終了させるにはどうすればよいですか? 親が実行される最初のpidであるため、これは達成されていませんが、変更方法がわかりません。

2.) 子プロセスを彼のように同時に実行するにはどうすればよいですか? 単なる偶然かどうかを確認するために、数値を非常に高く上げてみましたが、そうではないようです。

編集:ソリューション

1.) 内部デフォルトに 2 回の wait(NULL) の追加
2.) が発生していました。それを証明するために sleep(1) を使用しました。

私のコードは次のとおりです

#include <stdio.h>
int main() {
    int pid, i;
    pid = fork();
    switch(pid) {
        case -1:
            // error
            printf("Fork error");
            break;
        case 0:
            // child process
            printf("First child is born, my pid is %d\n", getpid());
            for(i=1; i<10; i++)
                printf("First child executes iteration %d\n", i);
            printf("First child dies quietly.\n");
            break;
        default:
            // parent process
            printf("Parent process is born, my pid is %d\n", getpid());
            pid = fork();
            switch(pid) {
                case -1:
                    // error
                    printf("Fork error");
                    break;
                case 0:
                    // child process
                    printf("Second child is born, my pid is %d\n", getpid());
                    for(i=1; i<10; i++)
                        printf("Second child executes iteration %d\n", i);
                    printf("Second child dies quietly.\n");
                    break;
                default:
                    // parent process
                    printf("Parent process dies quietly.");
        }
    }
    return 0;
}

私の出力は常に次のようになります。

親プロセスが誕生しました。私の pid は 7847 です  
最初の子供が生まれました、私の pid は 7848 です  
最初の子が反復を実行: 1  
最初の子が反復を実行: 2  
最初の子が反復を実行: 3  
最初の子が反復を実行: 4  
最初の子が反復を実行: 5  
最初の子が反復を実行: 6  
最初の子が反復を実行: 7  
最初の子が反復を実行: 8  
最初の子が反復を実行: 9  
最初の子が反復を実行: 10  
最初の子供は静かに死にます。  
親プロセスは静かに終了します。  
2人目の子供が生まれました、私のpidは7849です  
2 番目の子は反復 1 を実行します  
2 番目の子は反復 2 を実行します  
2 番目の子は反復 3 を実行します  
2 番目の子は反復 4 を実行します  
2 番目の子は反復 5 を実行します  
2 番目の子は反復 6 を実行します  
2 番目の子は反復 7 を実行します  
2 番目の子は反復 8 を実行します  
2 番目の子は反復 9 を実行します  
2 番目の子は反復 10 を実行します  
2番目の子供は静かに死にます。  

私の課題は次のとおりです。

3 つのプロセス (2 つの子プロセスを作成する親プロセス) を作成する C プログラム ("procs.c") を作成します。

最初の子は次のことを行う必要があります。

  • 表示「最初の子供が生まれました。私のpidは...」

  • 「最初の子が反復 X を実行します」というメッセージを 10 回表示します。ここで、X は反復の回数です。

  • 「最初の子供は静かに死ぬ」と表示します。

2 番目の子は、次のことを行う必要があります。

  • 表示 "2 番目の子供が生まれました。私の pid は ..."

  • 「2 番目の子が反復 X を実行します」というメッセージを 10 回表示します。ここで、X は反復の回数です。

  • 「二人目の子は静かに死ぬ」と表示。

親プロセスは次のことを行う必要があります。

  • 表示 "親プロセスが誕生しました。私の pid は ..."

  • 最初の子を作成します

  • 2 番目の子を作成します。

  • 「親プロセスは静かに終了します」と表示します。

gcc を使用してプログラムをコンパイルし、実行可能ファイルに「procs」という名前を付けます。プログラムを数回実行し、2 つの子の出力がどのようにインターレースするかを確認します。

このプログラムの可能な出力は次のとおりです。

新星> ./procs

親プロセスが誕生しました。私の pid は 7847 です  
最初の子供が生まれました、私の pid は 7848 です  
最初の子が反復を実行: 1  
最初の子が反復を実行: 2  
最初の子が反復を実行: 3  
最初の子が反復を実行: 4  
最初の子が反復を実行: 5  
2人目の子供が生まれました、私のpidは7849です  
2 番目の子は反復 1 を実行します  
2 番目の子は反復 2 を実行します  
2 番目の子は反復 3 を実行します  
最初の子が反復を実行: 6  
2 番目の子は反復 4 を実行します  
2 番目の子は反復 5 を実行します  
2 番目の子は反復 6 を実行します  
最初の子が反復を実行: 7  
2 番目の子は反復 7 を実行します  
2 番目の子は反復 8 を実行します  
2 番目の子は反復 9 を実行します  
2 番目の子は反復 10 を実行します  
2番目の子供は静かに死にます。  
最初の子が反復を実行: 8  
最初の子が反復を実行: 9  
最初の子が反復を実行: 10  
最初の子供は静かに死にます。  
親プロセスは静かに終了します。  
4

2 に答える 2

4
  1. 適切な親プロセスは、終了する前にその子プロセスが終了するまで待機する必要があります (またはプラットフォーム固有のバリアントを使用) wait()waitpid()

  2. 同時実行では、スケジューラが実行する機会を得る必要があります。適切なスリープ (マイクロスリープ、ナノスリープ) 操作で問題を強制できます。いくつかのシステム コールが役立ちます (fflush(0)役立つかもしれません)。


#include <stdio.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

int main(void)
{
    int pid, i;
    struct timespec tw = { .tv_sec = 0, .tv_nsec = 10000000 };
    pid = fork();
    switch(pid)
    {
        case -1:
            printf("Fork error");
            break;
        case 0:
            printf("First child is born, my pid is %d\n", getpid());
            for(i=1; i<10; i++)
            {
                printf("First child executes iteration %d\n", i);
                nanosleep(&tw, 0);
            }
            printf("First child dies quietly.\n");
            break;
        default:
            printf("Parent process is born, my pid is %d\n", getpid());
            pid = fork();
            switch(pid)
            {
                case -1:
                    printf("Fork error");
                    break;
                case 0:
                    printf("Second child is born, my pid is %d\n", getpid());
                    for(i=1; i<10; i++)
                    {
                        printf("Second child executes iteration %d\n", i);
                        nanosleep(&tw, 0);
                    }
                    printf("Second child dies quietly.\n");
                    break;
                default:
                    printf("Parent process waiting for children.\n");
                    int corpse;
                    int status;
                    while ((corpse = waitpid(0, &status, 0)) > 0)
                        printf("Child %d died with exit status 0x%.4X\n", corpse, status);
                    printf("Parent process dies quietly.\n");
                    break;
            }
    }
    return 0;
}

出力例:

Parent process is born, my pid is 46624
First child is born, my pid is 46625
First child executes iteration 1
Parent process waiting for children.
Second child is born, my pid is 46626
Second child executes iteration 1
First child executes iteration 2
Second child executes iteration 2
First child executes iteration 3
Second child executes iteration 3
First child executes iteration 4
Second child executes iteration 4
Second child executes iteration 5
First child executes iteration 5
Second child executes iteration 6
First child executes iteration 6
Second child executes iteration 7
First child executes iteration 7
Second child executes iteration 8
First child executes iteration 8
Second child executes iteration 9
First child executes iteration 9
First child dies quietly.
Second child dies quietly.
Child 46625 died with exit status 0x0000
Child 46626 died with exit status 0x0000
Parent process dies quietly.

10 ミリ秒の遅延により、ほぼ交互に実行されることに注意してください。似たようなものがなければ、システムとそのスケジューラーの特異性にとらわれてしまい、最新のマシンの多くは速すぎます!

于 2012-09-07T05:40:28.757 に答える
1

fork()親から独立して実行される新しい子プロセスを作成します。

子プロセスが終了するまで親プロセスを待機させたい場合はwait、プロセスが終了するまでブロックする PID を渡すシステム コールを使用できます。

ウィキペディアの記事wait(System Call) を参照してください

于 2012-09-07T05:37:34.267 に答える