システムコールと関数コールの違いは何ですか? fopen() はシステムコールですか、それとも関数コールですか?
10 に答える
システム コールはカーネル コードへの呼び出しであり、通常は割り込みを実行することによって実行されます。割り込みにより、カーネルが引き継いで要求されたアクションを実行し、制御をアプリケーションに戻します。このモード切り替えが、システム コールの実行が同等のアプリケーション レベル関数よりも遅い理由です。
fopen
内部で 1 つ以上のシステム コールを実行する C ライブラリの関数です。通常、C プログラマーがシステム コールを使用する必要はほとんどありません。これは、C ライブラリがシステム コールをラップしてくれるためです。
fopen は関数呼び出しです。
システム コールは、リソースを管理する基盤となる OS と対話します。システムコールを行ったプロセスの状態を保持するために多くの手順を実行する必要があるため、関数呼び出しよりもコストがかかります。
*nix システムでは、fopen は open をラップし、システム コールを実行します (open はシステム コールの C ラッパーです)。fread /read 、 fwrite / write などでも同じことが起こります。
ここには、UNIX syscall によって実行されるタスクの優れた説明があります。
実はシステムコールは関数呼び出しとは関係ありません。これら 2 つのメカニズムの唯一の共通点は、どちらも呼び出し元にサービスを提供することです。
スレッド実行の観点からシステムコールを確認するには:
システムコールとは、アプリケーションモードプログラムが下線OSの提供するサービスを要求する機能です。システム コールは、実行中のスレッドをユーザー モードからカーネル モードに移行し、システム コール ハンドラー関数を実行してから、ユーザー モードに戻ります。
システムコール パラメータ:
システムコールのパラメータは (syscall 番号, params...) です。params の意味と形式は、syscall 番号によって異なります。
ユーザーランドプログラムに提供されるsyscallライブラリの観点から:
ユーザーモードプログラムは通常、glibc のライブラリを呼び出してシステムコールを呼び出します。たとえば、glibc の open() 関数は次のようになります。
- システムコール番号SYS_OPENをeaxレジスタに入れる
- ソフトウェア割り込みまたは sys_enter 命令を呼び出してシステム コールを要求する
Linuxを使用している場合は、straceを介してアプリケーションによって実行されるシステムコールを監視できます。
strace /path/to/app
その出力は、libc内で何が起こっているのか、そしてどの関数が実際にシステムコールであるのかについての良い洞察を与えるかもしれません。
この議論に追加する観点は、一般的に最も楽観的な場合の関数呼び出しには、x86でいくつかの8ビット命令(平均で4-10)のオーバーヘッドがあるということです。
システムコールには、次のプロパティがあります。
- はるかに多くの命令を実行します。単にスタック状態ではなく、プロセスをフリーズする必要があります。
- 関連するタイミングは、ほとんど決定論的ではありません。
- 多くの場合、これはスケジューリングスポットであり、スケジューラーは再スケジュールを選択する場合があります。
これらの3つの原始的な理由(おそらくもっとある)のために、可能な限りシステムコールの量を減らす必要があります-たとえば、ネットワーク化されたシステムソフトウェアは、新しいものに割り当てるためにソケットハンドル(および接続によって使用される他のアプリケーション固有の内部データ構造)を保持します接続、なぜカーネルを気にするのですか?
ソフトウェアは逆さまのピラミッドのように構築されていることを忘れないでください。システムコールはベースにあります。
システム コールは、実際にはカーネル空間によって実行される API を呼び出します。これが想定するすべての関連コストで(詳細については、Wikiまたはこのリンクを参照してください)
関数呼び出しは、ユーザー空間内のコードの一部への呼び出しです。
ただし、関数呼び出しは、その実行プロセスでシステム呼び出しを行う関数に対するものである可能性があることに注意してください。「fopen」はそのような例の 1 つです。したがって、fopen 自体の呼び出しは関数の呼び出しですが、実際の IO を処理するためにシステム コールが発生しないという意味ではありません。
他の人が提示した図を完成させるために、通常はラッパーとして実装さfopen
れます。これは、ユーザーがアクセスできる機能でもあります。ある意味では、それが返す構造がユーザーのためにものをカプセル化するので、より高いレベルです。一部のユーザーは、特別なニーズに直接使用します。したがって、「システムコール」を呼び出すのは正しくありません。また、ユーザーが呼び出すことができる関数であるため、システムコールを直接実行することもありません。open
fopen
open
FILE*
open
fopen
open
fopen
は関数呼び出しですが、最終的には「システム」(OS) によって処理されるため、システム コールと呼ばれることもあります。 C ランタイム ライブラリfopen
に組み込まれています。