19

フォークをするのは本当に初めてですが、このコードで pid は何をしているのですか? 行 X と行 Y で何が表示されるか説明してもらえますか?

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#define SIZE 5
int nums[SIZE] = {0,1,2,3,4};
int main()
{
    int i;
    pid_t pid;
    pid = fork();
    if (pid == 0) {
        for (i = 0; i < SIZE; i++) {
            nums[i] *= -i;
            printf("CHILD: %d ",nums[i]); /* LINE X */
        }
    }
    else if (pid > 0) {
        wait(NULL);
        for (i = 0; i < SIZE; i++)
            printf("PARENT: %d ",nums[i]); /* LINE Y */
    }
    return 0;
}
4

4 に答える 4

28

fork()プロセスを複製するため、 fork を呼び出した後、実際には実行中のプログラムのインスタンスが 2 つあります。

どのプロセスが元の (親) プロセスで、どのプロセスが新しい (子) プロセスであるかをどのように知ることができますか?

親プロセスでは、子プロセスの PID (正の整数) が から返されfork()ます。if (pid > 0) { /* PARENT */ }それがコードが機能する理由です。子プロセスでは、fork()を返すだけ0です。

したがって、if (pid > 0)チェックのために、親プロセスと子プロセスは異なる出力を生成します。これは、ここで確認できます(コメントで @jxh によって提供されているように)。

于 2013-02-27T01:39:34.693 に答える
4

このfork()関数は、実際には 2 回 (親プロセスに 1 回、子プロセスに 1 回) 返すという点で特別です。親プロセスでfork()は、子の pid を返します。子プロセスでは 0 を返します。エラーの場合、子プロセスは作成されず、親プロセスには -1 が返されます。

の呼び出しが成功するfork()と、子プロセスは基本的に親プロセスの正確な複製になります。どちらも、すべてのローカル変数とグローバル変数の独自のコピーと、開いているファイル記述子の独自のコピーを持っています。両方のプロセスが同時に実行され、同じファイル記述子を共有しているため、各プロセスの出力は相互にインターリーブされる可能性があります。

質問の例を詳しく見てみましょう。

pid_t pid;
pid = fork();
// When we reach this line, two processes now exist,
// with each one continuing to run from this point
if (pid == 0) {                    
    // The child runs this part because fork returns 0 to the child
    for (i = 0; i < SIZE; i++) {
        nums[i] *= -i;
        printf("CHILD: %d ",nums[i]); /* LINE X */
    }
}
else if (pid > 0) {
    // The parent runs this part because fork returns the child's pid to the parent
    wait(NULL);     // this causes the parent to wait until the child exits
    for (i = 0; i < SIZE; i++)
        printf("PARENT: %d ",nums[i]); /* LINE Y */
}

これにより、次のように出力されます。

CHILD: 0 CHILD: -1 CHILD: -4 CHILD: -9 CHILD: -16 PARENT: 0 PARENT: 1 PARENT: 2 PARENT: 3 PARENT: 4

親プロセスが呼び出すためwait()、子が終了するまでその時点で一時停止します。したがって、子の出力が最初に表示されます。次に、子が終了した後、親はwait()呼び出しの後から続行し、次にその出力を出力します。

于 2015-12-14T14:32:57.793 に答える