web-dev-qa-db-ja.com

「Cシステムコール」と「Cライブラリルーチン」の違いは何ですか?

マンページには複数のセクションがあります。それらの2つは次のとおりです。

 2つのUnixおよびCシステムコール
 3つのCプログラム用のCライブラリルーチン

たとえば、 getmntinfo(3)getfsstat(2) があり、どちらも同じことをしているように見えます。いつどちらを使用する必要があり、違いは何ですか?

23
Georg Schölly

システムコールは、UNIXの場合と同様に、オペレーティングシステム関数です。 malloc() 関数は sbrk() システムコール(プロセスメモリスペースのサイズ変更用)。

ライブラリは、オペレーティングシステムの一部ではない単なるアプリケーションコードであり、多くの場合、複数のOSで利用できます。これらは基本的に、独自のプログラム内の関数呼び出しと同じです。

線は少しぼやけている可能性がありますが、システムコールをカーネルレベルの機能として表示するだけです。

30
cletus

共通関数のライブラリはシステムコールインターフェイスの上に構築されていますが、アプリケーションは両方を自由に使用できます。

システムコールは、カーネルリソースを使用するためのアクセス権を持つ認証キーのようなものです。

enter image description here

上の画像は高度なLinuxプログラミングからのものであり、ユーザーアプリがカーネルとどのように相互作用するかを理解するのに役立ちます。

14
shingaridavesh

システムコールは、ユーザーレベルのコードとカーネルの間のインターフェイスです。 Cライブラリルーチンは他のルーチンと同じようにライブラリ呼び出しであり、たまたま実際に一般的に提供されています(ほぼ普遍的に)。標準ライブラリルーチンの多くは、システムコールのラッパー(薄いかどうかに関係なく)であり、線が少しぼやける傾向があります。

どちらを使用するかについては、原則として、ニーズに最も適したものを使用してください。

12
womble

マニュアルのセクション2で説明されている呼び出しはすべて、カーネルにトラップするシステムサービスへの実際の呼び出しの比較的薄いラッパーです。マニュアルのセクション3で説明されているC標準ライブラリルーチンは、実際にシステムコールを使用する場合と使用しない場合があるクライアント側のライブラリ関数です。

この投稿 システムコールとカーネルへのトラップ(わずかに異なるコンテキスト)の説明があり、いくつかの参照を使用してシステムコールの背後にある基本的なメカニズムを説明しています。

原則として、常にCライブラリバージョンを使用する必要があります。多くの場合、シグナルの再起動などの難解な処理を行うラッパーがあります(要求した場合)。これは、すでにライブラリにリンクしている場合に特に当てはまります。すべてのルールには違反する理由があります。直通電話を利用する理由、

  1. libcにとらわれないようにしたい。多分インストーラーで。このようなコードは、使用するライブラリに関係なく、Android( bionic )、 Clibc 、およびより従来のglibc/eglibcシステムで実行できます。 、ラッパーを使用した動的ロードにより、Android/Linuxのデュアルバイナリを可能にするランタイムglibc/bionicレイヤーを作成します。
  2. 極端なパフォーマンスが必要です。これはおそらくまれであり、おそらく誤った方向に進んでいますが。おそらく、問題を再考することでパフォーマンスが向上し、notシステムを呼び出すことは、多くの場合、パフォーマンスの向上につながります。これは、libcがときどき行うことができます。
  3. ライブラリなしでinitramfsまたはinitコードを記述しています。より小さなイメージを作成するか、より速く起動します。
  4. あなたは新しいカーネル/プラットフォームをテストしていて、本格的なファイルシステムで人生を複雑にしたくありません。 initramfsと非常によく似ています。
  5. プログラムの起動時に非常に迅速に何かを実行したいが、最終的にはlibcルーチンを使用したい。
  6. libcの既知のバグを回避するため。
  7. この機能は、libcからは利用できません。

申し訳ありませんが、ほとんどの例はLinux固有のものですが、その根拠は他のUnixバリアントにも当てはまるはずです。最後の項目は、新しい機能がカーネルに導入されたときに非常に一般的です。たとえば、 kqueue または epoll が最初に導入されたとき、それらをサポートするlibcはありませんでした。これは、システムに古いライブラリがあり、新しいカーネルがあり、この機能を使用したい場合にも発生する可能性があります。

プロセスがlibcを使用していない場合は、システム内の何かが使用している可能性があります。独自のバリアントをコーディングすることで、同じ最終目標への2つのパスを提供することでキャッシュを無効にすることができます。また、Unixはプロセス間でコードページを共有します。通常、libcバージョンを使用しない理由はありません。

他の回答は、libcとシステムコールの違いについてすでに素晴らしい仕事をしています。

4
artless noise