13

システムコールの勉強を始めたばかりです。システムコールが行われたときのオーバーヘッドの原因を知りたいです。

たとえば、getpid() を考えると、システム コールが getpid() に対して行われるとき、コントロールが現在子プロセスにある場合、親プロセスに入って pid を取得するためにコンテキスト切り替えを行う必要があると思います。 . それはオーバーヘッドに貢献できますか?

また、getpid() が呼び出されると、ユーザー空間の境界を越えてメタデータが転送され、カーネルに出入りします。したがって、ユーザー空間とカーネルの間の絶え間ない切り替えもオーバーヘッドを引き起こしますか?

4

3 に答える 3

6

たとえば、getpid() を考えると、システム コールが getpid() に対して行われるとき、コントロールが現在子プロセスにある場合、親プロセスに入って pid を取得するためにコンテキストの切り替えを行う必要があると思います。 .

ここでは、子プロセスへのコンテキスト スイッチは必要ありません。カーネルは、必要なデータをすべて自身で利用できるようにする必要があります。ほとんどの場合、カーネルは、スケジューラのユーザー空間プロセスにコンテキストを切り替えるか、システム コールから戻るときにのみ切り替えます。

また、getpid() が呼び出されると、ユーザー空間の境界を越えてメタデータが転送され、カーネルに出入りします。ユーザー空間とカーネルの間の絶え間ない切り替えもオーバーヘッドを引き起こしますか?

はい、getpid()頻繁に呼び出された場合、オーバーヘッドは確実に増加します。やのような単純な「getter」システム コールのこのオーバーヘッドを回避できるアプローチがいくつかありgetpid()ますgettimeofday()。ある時点で Linux で使用されたそのようなアプローチの 1 つは、システム コールの (既知の) 結果を特別なメモリ ページに格納することでした。(このメカニズムはvsyscallと呼ばれていました。)

于 2014-05-12T02:35:56.820 に答える
4

(すべての文を修飾するのではなく)一般化することをお許しください。

システム サービスへの呼び出し (プロセス情報を返すなど) には、ユーザー モード シェルがあります。このシェルは、カーネル モード システム サービスを呼び出すシステム ディスパッチ テーブルを介してルーティングされる例外をトリガーします。

カーネル モードへの切り替えには、プロセス コンテキストの切り替えに似たものが必要です。たとえば、ユーザー スタックから kern スタックへの変更 (およびその他のシステム依存の変更) が必要です。

呼び出しプロセスは、ユーザー モードのリターン バッファーを提供します。システム システム サービスは、セキュリティ上の目的で応答データを書き込む前に、有効なユーザー モード バッファーであることを確認します。

現在のプロセスに関する情報のみを返す getpid のようなライブラリ関数は、カーネル モードへの切り替えを必要としない場合があります。

于 2014-05-12T04:47:13.780 に答える