10

fork システムコールコードはどのように書かれていますか。関数が2つの異なる値を返す方法と、それを2つの異なるプロセスに返す方法の詳細を知りたいです。つまり、fork システム コールがどのように実装されているか知りたいですか?

4

4 に答える 4

13

カールの答えは素晴らしかった。多くのオペレーティング システムでは、戻り値がレジスタの 1 つに渡されることを付け加えておきます。x86 アーキテクチャでは、このレジスタは eax である可能性があり、ARM アーキテクチャでは、このレジスタは R0 である可能性があります。

各プロセスにはプロセス制御ブロック (PCB) もあり、割り込み、システムコール、または例外が発生して制御が OS に渡された時点でレジスタの値を格納します。次にプロセスがスケジュールされたときに、レジスターの値が PCB から復元されます。

fork() が発生すると、OS は次のことを実行できます。

 child_process->PCB[return_value_register] = 0;
 parrent_process->PCB[return_value_register] = child_pid;

そのため、プロセスが再スケジュールされると、それぞれが異なる戻り値を参照します。

例として、 xv6 の fork の実装を見ることができます。そこでは、親プロセスはまだ実行中の状態にあるため、単純な return ステートメントを使用して親の戻り値を返します。ただし、子プロセスの EAX レジスタの値を 0 に設定するため、子プロセスがスケジュールされると、戻り値として 0 が表示されます。

// Clear %eax so that fork returns 0 in the child.
np->tf->eax = 0;

return 0 も "mov eax, 0" のようなものにコンパイルされることに注意してください。

更新:私がやっている趣味の OS に fork() を実装しました。ソースコードはこちらで見ることができます。

于 2014-08-21T15:07:24.033 に答える
10

あなたはそれがシステムコールだと言ってほとんど説明しました。すべての作業を行うのはオペレーティング システムの仕事であり、オペレーティング システムは、プログラムのコンテキストや、実装している言語の規則の外で、必要なことはほとんど何でも行うことができます。起こる:

  1. プログラムコールfork()システムコール
  2. カーネルフォークシステムコールは、プログラムを実行しているプロセスを複製します
  3. カーネルは、元のプログラムと複製のシステム コールの戻り値を設定します (それぞれ、複製の PID と 0)。
  4. カーネルは両方のプロセスをスケジューラ キューに入れます
  5. 各プロセスがスケジュールされると、カーネルは 2 つのプログラムのそれぞれに「戻ります」。
于 2012-01-13T22:05:42.340 に答える
3

大学向けのUnix V6ソース コード ブックレットには、Ken Thompson と Dennis Ritchie 自身が注釈を付けたコメントがあり、ダブル リターンが実際にどのように機能するかを説明しています。コメントは次の文で終わります。

これを理解することは期待されていません。

于 2012-01-13T22:25:40.467 に答える
-2

簡単な方法では、たとえば、プロセスはfork()移動IP/EIP/RIPレジスタを使用して関数に複製され、次のような関数の命令をスキップします。

return pid;
return 0;

最初のプロセスは最初の命令を実行し、スタックから関数をポップし、2 番目のプロセスは開始しますが、2 番目の命令から 0 を返します。

于 2012-01-13T22:05:55.837 に答える