私は「オペレーティングシステムの概念」を自分で教えており、chp3作業をしています。クラフトパーツ。
"fork()" 関数が呼び出され、次のように返される pid 値に依存する例があります。
pid=fork();
if(pid<0){ //error stuff
}
else if(pid==0){
// child process stuff
}
else{
// parent process stuff
}
ここで混乱しているのは、このコードが実行されると「if」の3つのケースのうちの1つだけが実行されることです。これは、親/子プロシージャの1つだけが実行されることを意味します。
ところで、ちょっと読んでみると、私の混乱を解決するのに役立つかもしれませんが、完全には解決できない文章があることがわかりました。
新しいプロセスは、元のプロセスのアドレス空間のコピーで構成されます。
私の想像では、これは「fork()」呼び出しが実行されるたびにそのコードの正確なコピーがコピーされて「子」プロセスとして実行されるのに対し、元のCコードは「親」プロセスとして実行されることを意味しているようです。 。 。
私がこれを理解するのは正しいですか?
また、「住所空間」はこれにどのような関係がありますか?もう一度、私の想像力を使用して親コードを実行するとは、コードがRAMにロードされ、コードに割り当てられたRAMセグメントがある場所で実行されることを意味するため、そのセグメントが新しいセグメントにコピーされると仮定します。 RAM内の他の場所に配置され、子プロセスに割り当てられます。
私の理解は正しいですか?
答え1
はい、そうです。
特に、これは、子プロセスが親プロセスから分岐したときに持っていたすべての変数と値を継承することを意味します。しかし、後のステップで、親または子プロセスのいずれかがこれらの変数のいずれかを変更する場合、その変更はそのプロセスに限定されます。子が変数を変更している場合、親は新しい値の代わりに古い値を表示し続けます。
分岐の場合、子プロセスと親プロセスが通信できるようにするには、明示的なプロセス間通信を使用する必要があります。
これがスレッドとの違いです。概念的には、フォークとスレッドは同じように見えます。フォークの場合、同じコードが両方のプロセスによって実行され、スレッドの場合、同じコードが2つのスレッドによって実行されます。ただし、スレッドの場合、アドレス空間はコピーされません: 2 つのスレッドが同じメモリを共有するため、1 つのスレッドが変数を変更すると他のすべてのスレッドに影響します。
したがって、スレッドはスレッド間で非常に柔軟な通信を可能にしますが、注意深く使用しないと競合状態が発生する可能性が高いため、エラーが発生しやすいです。
どちらのシステムも異なる要件を満たしています。参考までに、フォークプリミティブは通常、システム側で賢い方法で実装されています。アドレス空間は物理的にコピーされませんが、システムは書き込み時にコピーシステムを使用するためです。データは次の場合にのみコピーされます。次のいずれかの条件が満たされます。プロセスは実際に修正を試みます。データは変更されませんが、コピーされないため、より多くのメモリを消費しません。
フォークとスレッドに関する追加情報StackOverflowにあります。。