標準ファイル記述子を持つプロセスは何ですか?

標準ファイル記述子を持つプロセスは何ですか?

正しい声明はどれですか?

すべてのUnixプロセスは、標準入力、標準出力、標準エラーなどの標準ファイル記述子を開きます。

または

端末に接続されているすべてのUnixプロセスは、標準入力、標準出力、標準エラーなどの標準ファイル記述子を開きます。

答え1

彼らはすべて間違っていた。

sleep 999 <&- >&- 2>&-
^C

Unixプロセスはsleep 999標準ファイル記述子を開いていませんが、Control-Cを使用して終了できるため、端末に接続されています。

答え2

選択式の質問の場合は、最初の質問を確認してください。先生はこれらの標準ファイル記述子通常端末に接続されたプロセスだけでなく、すべてのプロセスに開いています。

ただし、開始時に最初のプロセスに加えて、どのプロセスもこれらの開始に合格することは絶対に保証されません。 2番目のステートメントがより正確であると主張することができます。なぜなら、これが開かないと、もはや実際に端末に接続されていないからです(論争の余地があります)。


事実は何ですか?

すべてのプロセスが許可されます閉鎖()または、STDIN STDOUT STDERR を含むファイル記述子を置き換えます。一度閉じたら、彼らはします消えたそして、もはやFDとして存在しません。子プロセスが保持するすべてのファイル記述子は、親プロセスから継承されます。したがって、プロセスがこれら 3 つの標準ファイル記述子を閉じてからサブプロセスを作成すると、そのサブプロセスもそのファイル記述子を所有しません。

明らかに、これは間違っています。

したがって、プロセス生成システムコールは、3つの標準ファイル記述子を使用してすべてのプロセスを生成しますが、一部のプロセスは端末から分離されます。

親プロセスがディスクリプタを交換せずに閉じて端末から切り離された場合dup2()、子供はそれを持っていません。その子供が自分の子供を作ったなら、「孫」もその子供を持たないでしょう…


これに対する posix 参照のためには、プログラムの実行が通常次の組み合わせで実行されることを理解する必要があります。

  • fork()子プロセスの開始
  • execve()子プロセスで別のプログラムを実行する

POSIXによるとfork() はすべてのファイル記述子を継承します。

子プロセスには、親プロセスのファイル記述子の独自のコピーが必要です。各子項目のファイル記述子は、親項目の対応するファイル記述子と同じオープンファイル記述を参照する必要があります。

倒れる危険性があります。一部のファイル記述子は、呼び出し時に自動的に閉じるように設定できます。実装する():

呼び出しプロセス・イメージでオープンされたファイル記述子は、実行クローズ・フラグFD_CLOEXECが設定されたファイル記述子を除いて、新しいプロセス・イメージでオープンされたままになります。

したがって、親プログラムがファイル記述子を明示的に閉じない場合でも、サブプログラムのファイル記述子が存在しない可能性があります。

答え3

すべての敵対的なコメントに対して、次の答えを提案します。

プロセスが常に開く3つのファイルは何ですか?

これには POSIX 標準へのリンクが含まれています。

https://pubs.opengroup.org/onlinepubs/009695399/functions/stdin.html

プログラムの開始時に3つのストリームを事前定義する必要があり、明示的に開く必要はありません。標準入力(標準入力読み取り用)、標準出力(標準出力書き込み用)、標準エラー(診断出力書き込み用)。オープン時に標準エラーストリームは完全にバッファリングされません。標準入力ストリームと標準出力ストリームは、標準入力ストリームと標準出力ストリームが対話型デバイスを参照していないと判断できる場合にのみ完全にバッファリングされます。

関連情報