私は自分で「オペレーションシステムの概念」を勉強しており、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つのスレッドで同じコードが実行されます。ただし、スレッドの場合、アドレス空間はコピーされません:2つのスレッドは同じメモリを共有するため、1つのスレッドが変数を変更すると、他のすべてのスレッドに影響します。
したがって、スレッドはスレッド間の非常に柔軟な通信を可能にしますが、慎重に使用しないと競合状態になる可能性が高いため、これもエラーが発生しやすくなります。
どちらのシステムも異なるニーズに対応しています。補足として、アドレスプリミティブは物理的にコピーされないため、フォークプリミティブは通常システム側で巧妙な方法で実装されますが、システムはコピーオンライトシステムを使用します。データが複製されるのは、プロセスは実際にそれを変更しようとします。データは変更されませんが、複製されないため、メモリを消費しません。
フォークとスレッドに関する詳細情報 StackOverflowにあります 。