2012-01-13 6 views
7

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

+3

Linuxカーネルのソースコードを試してみることができます... – fge

+1

OSはプロセスを作成できるという考えに慣れており、各プロセスのアドレス空間にマップするメモリ領域を選択できますか? –

+0

これにはどのような点がありますか? – Svisstack

答えて

9

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

  1. プログラムが
  2. カーネルforkシステムコールは、プログラム
  3. を実行しているプロセスを複製カーネルは元のプログラムのために、重複のためのシステムコール(PIDのための戻り値を設定しますfork()システムコールを呼び出します複製と0、それぞれ)
  4. カーネルは、両方のプロセスをスケジューラキュー
  5. 各プロセスがスケジュールされると、カーネルは2つのプログラムのそれぞれに「戻る」。例えば、プロセスのための簡単な方法で
-1

は、のように見えることができます機能にいくつかの命令をスキップしIP/EIP/RIPにレジスタを移動するとfork()機能でクローン化されています

return pid; 
return 0; 

最初のプロセスが最初に実行されます命令とポップ機能がスタックから始まるが、2番目の命令は0を返す2番目の命令から開始する。

+0

私はそれが、各プロセスのシステムコールから異なる値を返すカーネルだと思います。 – tangrs

+0

fork()を呼び出すと、両方のプロセスフォークが同じポイントからフォークします。私はあなたが "二番目"のプロセス(親または子)によって何を意味するのか分かりませんが、それ自体が二重に返ってくるのではなく、それに使用されているアセンブリーを指す間違った – iantonuk

2

Unix V6 Ken Thompsによって注釈付けされた大学のソースコードブックレットにはコメントがあるデニス・リッチー自身がダブルリターンが実際にどのように機能するかを記述しています。コメントは次の文で終わります。

これは分かりません。

+0

IIRCです。 – ninjalj

7

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

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

、フォーク()が発生したときに、OSが行うことができます:プロセスが再スケジュールされている場合

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

をので、それらのそれぞれは、異なる戻り値を参照してください。

例として、xv6's implementation of forkが表示されます。そこで、親プロセスはまだ実行状態にあるので、単純なreturn文を使用して親の戻り値を返します。しかし、それは子プロセスが予定されているときに、それは戻り値として0を見て、0に子プロセスのためのEAXレジスタの値を設定します。

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

0を返す注意も「MOVのEAX、0」のようなものにコンパイルされます。

更新:私は趣味のOSでfork()を実装しています。ソースコードはhereです。