2011-07-11 18 views
7
int main() 
{ 
    int data_processed; 
    int file_pipes[2]; 
    const char some_data[] = "123"; 
    char buffer[BUFSIZ + 1]; 
    pid_t fork_result; 

    memset(buffer, '\0', sizeof(buffer)); 

    if (pipe(file_pipes) == 0) { 
     fork_result = fork(); 
     if (fork_result == -1) { 
      fprintf(stderr, "Fork failure"); 
      exit(EXIT_FAILURE); 
     } 

// We've made sure the fork worked, so if fork_result equals zero, we're in the child process. 

     if (fork_result == 0) { 
      data_processed = read(file_pipes[0], buffer, BUFSIZ); 
      printf("Read %d bytes: %s\n", data_processed, buffer); 
      exit(EXIT_SUCCESS); 
     } 

// Otherwise, we must be the parent process. 

     else { 
      data_processed = write(file_pipes[1], some_data, 
            strlen(some_data)); 
      printf("Wrote %d bytes\n", data_processed); 
     } 
    } 
    exit(EXIT_SUCCESS); 
} 

は私の理解に基づいて、フォークで作成された子プロセスは、親プロセスと変数を共有しません。次に、なぜ親が1つのファイル記述子に書き込むことができ、子プロセスが別のファイル記述子から読み込むことでデータを取得できるのか。これは内部的にパイプ機能によって何とか制御されているからですか?forkの後、親プロセスと子プロセスがパイプで作成されたファイル記述子を共有しますか?

答えて

14

パイプを含むファイル記述子は、forkに複製されます。子プロセスは、stdin/out/errとパイプを含む同じファイル記述子テーブルで終わります。

私の理解に基づいて、forkによって作成された子プロセスは、親プロセスと変数を共有しません。

これは完全に真実ではない - は、変数へのが親と共有されていない変更されますが、前フォークに親がすぐに持っていた値は、その後のすべての子に表示されます。いずれの場合においても

、パイプは、オペレーティング・システム内ではなく、プロセス内に存在します。このように、パイプの一端に書き込まれたデータは、他端のFDを保持する他のプロセスから見えるようになります。 (複数のプロセスがデータを読み取ろうとする場合は、read()データにしようとする最初のプロセスがそれを取得し、他のプロセスが逃す。)

5

変数は、例えば、共有されていません子にfile_pipes[0] = 999と書き込むと、親に反映されません。ファイル記述子が共有されている(子におけるFD番号xは、親でFD番号xと同じものを指します)。これは、(たとえば)他のコマンドを実行するシェルスクリプトの出力をリダイレクトすることができる理由です(同じ標準出力ファイル記述子を共有するためです)。

1

あなたは正しいです - 普通の間で共有さではありません変数は、親と子供。

はしかし、パイプは変数ではありません。それらは、2つの独立したプロセスを一緒に接続するように特別に設計された疑似ファイルです。パイプに書き込むときは、現在のプロセスで変数を変更していません。オペレーティングシステムにデータを送信し、パイプから読み込むために次のプロセスでそのデータを利用できるようにすることを求めています。

それはちょうどあなたが本当の、ディスク上のファイルに書き込むときのようなものだ - データがディスクに書き込まれていないことを除いて、それはちょうどパイプの他端に使用可能になります。

関連する問題