ファイルIOと標準IOの違い

まず、ファイル I/O と標準 I/O とは何かを理解しましょう。

ファイル I/O:ファイル I/O は、キャッシュを使用しない IO (バッファなし I/O) と呼ばれます。キャッシュがないということは、すべての読み取りと書き込みがカーネル内のシステム コールを呼び出すことを意味します。これは一般に、低レベル I/O と呼ばれます。オペレーティング システムによって提供され、OS にバインドされ、Linux または UNIX プラットフォームに固有の基本的な I/O サービスです。

標準 I/O:標準 I/O は、ANSI C で定められた標準 I/O モデルで、標準機能パッケージと stdio.h ヘッダ ファイルで定義されており、一定の移植性があります。標準 I/O ライブラリは、詳細の多くを処理します。キャッシュの割り当て、最適化された長さでの I/O の実行など。標準 I/O は 3 種類のバッファを提供します。

(1) キャッシュがいっぱい: 実際の I/O 操作は、標準 I/O キャッシュがいっぱいになった後にのみ実行されます。 
(2) 行バッファ: 入力または出力で改行文字が出現すると、標準 I/O ライブラリが I/O 操作を実行します。 
(3) キャッシュなし: stderr で十分です。

第二に、両者の違いは、

      ファイル I/O は 、低レベル ディスク I/O とも呼ばれ、POSIX 関連の標準に従います。ファイル I/O は、POSIX 準拠のオペレーティング システムでサポートされています。標準 I/Oはアドバンスト ディスク I/O と呼ばれ、ANSI C 関連の規格に従います。標準 I/O は、開発環境で標準 I/O ライブラリが利用可能であれば使用できます。(GLIBC は、標準 C ライブラリのスーパーセットである Linux で使用されます。GLIBC には、ANSI C で定義された関数だけでなく、POSIX 標準で定義された関数も含まれています。したがって、標準 I/O とファイル I/O の両方が含まれます)。

      ファイル I/O を通じてファイルを読み書きする場合、各操作で関連するシステム コールが実行されます。このアプローチの利点は、実際のファイルを直接読み書きできることです。欠点は、頻繁なシステム コールによりシステムのオーバーヘッドが増加することです。標準 I/O は、ファイル I/O に基づいてカプセル化されたバッファ メカニズムとみなすことができます。最初にバッファの読み取りと書き込みが行われ、必要に応じて実際のファイルにアクセスするため、システム コールの数が削減されます。

      ファイル I/O では、ファイル記述子は開いているファイルを表すために使用され、通常のファイル、デバイス ファイル、パイプライン ファイルなどのさまざまな種類のファイルにアクセスできます。標準 I/O では、FILE (ストリーム) は開いているファイルを表すために使用されます。これは通常、通常のファイルにアクセスするためにのみ使用されます。

3. 最後に、使用する関数を確認します。

 

標準IO

ファイルIO(低レベルIO)

開ける

fopen、freopen、fdopen

開ける

閉鎖

f閉じる

近い

読む

getc、fgetc、getchar
fgets、
freadを取得

読む

書く

putc、fputc、putchar
fputs、puts、
fwrite

書く

1.fopen与open

標準 I/O は、 fopen 関数を使用してファイルを開きます。

FILE* fp=fopen(const char* パス,const char *mod)

path はファイル名で、mod は「r」、「w」、「w+」、「a」などのファイルを開くモードの文字列を指定するために使用されます。文字 b を追加して開くことを指定できます。バイナリ モード (*nix システムの場合、ファイル タイプは 1 つだけであるため、違いはありません) では、ファイルが正常に開かれた場合は FILE ファイル ポインタが返され、失敗した場合は NULL が返されます。実際のファイルを指すのではなく、ファイル情報パッケージに関するデータを指します。これには、ファイルによって使用されるバッファー情報が含まれます。

ファイル IO は、open 関数を使用してファイルを開きます。

int fd=open(char *name,int how);

fopen と同様に、name はファイル名の文字列を表し、オープン モードを指定する方法: O_RDONLY (読み取り専用)、O_WRONLY (書き込み専用)、O_RDWR (読み取りおよび書き込み可能)、およびその他のモードを指定します。man 2 open してください。正の整数を返すことに成功した場合はファイル記述子と呼ばれますが、これは標準 I/O とは大きく異なります。失敗した場合に -1 を返すことも、NULL を返す標準 I/O とは異なります。

2.f閉じると閉じる

ファイルを開くのとは対照的に、標準 I/O は fclose を使用してファイルを閉じ、ファイル ポインタを渡すだけです。正常に閉じられた場合は 0 を返し、そうでない場合は EOF を返します。次に例を示します

if(fclose(fp)!=0)  
            printf("ファイルを閉じる際のエラー");

ファイル IO は、open によって開かれたファイルを閉じるために close を使用します。これは fclose と似ていますが、エラーが発生した場合に EOF の代わりに -1 が返され、正常に閉じられた場合にも 0 が返される点が異なります。C 言語では、エラー処理にエラー コードを使用します。

3. ファイルgetc、fscanf、fgets を読み取り、読み取ります

標準 I/O でのファイル読み取りの場合、getc を使用して文字ごとに読み取ることも、gets (標準 io 読み取りの読み取り)、fgets を使用して文字列単位で読み取ることもできます (改行文字の後に最初に見つかったものまで読み取ります)。 (パラメーター、ファイル ポインターを受け入れます) は、ターゲット配列が読み取られた文字を収容できるかどうかを判断しません。これにより、ストレージ オーバーフローが発生する可能性があります (推奨されません)。 fgets は 3 つのパラメーターを使用します: char * fgets ( char *s、int size、
FILE *ストリーム);

最初のパラメータは gets と同じで、入力アドレスを格納するために使用されます。2 番目のパラメータは入力文字列の最大長を示す整数で、最後のパラメータは読み取られるファイルを指すファイル ポインタです。最後の fscanf は、scanf に似ていますが、fscanf(fp,"%s",words) など、操作するファイルを指定するパラメーターが追加され、ファイル IO で読み取り関数が使用されて読み取ります。 open 関数で開いたファイル、
関数 プロトタイプは次のとおりです。

ssize_t numread=read(int fd,void *buf,size_t qty);

このうち、fd は open によって返されるファイル記述子、buf はデータの目的のバッファを格納するために使用され、qty は読み取られるバイト数を指定します。正常に読み取られた場合は、読み取られたバイト数 (qty 以下) を返します。

4. ファイルの終わりを確認する

標準 IO の getc は、読み取り試行がファイルの終わりに達すると特別な値 EOF を返します。一方、fgets は EOF に遭遇すると NULL を返しますが、*nix 読み取り関数の場合は状況が異なります。read は qty で指定されたバイト数を読み込みますが、最終的に読み出したデータは要求した量 (qty) に満たない可能性があり、最後まで読んでから読みたい場合、read 関数は 0 を返します。

5. ファイルの書き込み: putc、fputs、fprintf、write

ファイルの読み取りに対応して、標準 C 言語 I/O は putc を使用して次のような文字を書き込みます。

putc ( ch , fp );

最初の引数は文字で、2 番目の引数はファイル ポインタです。fputs は次のようになります。

fputs(buf,fp);

最初のパラメータのみが文字列アドレスに置き換えられます。fprintf は printf に似ていますが、書き込むファイルを指定するパラメーターを追加します。次に例を示します。

fprintf(stdout,"こんにちは %s。\n","デニス");

fscanf と fprintf は最初のパラメータとして FILE ポインタを受け取り、putc と fputs は 2 番目のパラメータを取ることに注意してください。

ファイルを書き込むためのファイル IO には書き込み関数が提供されており、プロトタイプは読み取りに似ています。

ssize_t result=write(int fd,void *buf ,size_t amt);

fd はファイル記述子、buf は書き込まれるメモリ データ、amt は書き込まれるバイト数です。書き込みが成功した場合は書き込んだバイト数を返し、その結果をamtと比較することで書き込みが正常かどうかを判断できます 書き込みに失敗した場合は-1を返します

6. ランダムアクセス: fseek()、ftell()、lseek()

標準 I/O はファイルへのランダム アクセスに fseek と ftell を使用します。まず fseek 関数のプロトタイプを見てください。

int fseek(FILE *stream, long offset, int wherece);

第一引数はファイルポインタ、第二引数は始点からの移動距離を示すlong型のオフセット(offset)です。3 番目のパラメーターは開始点を指定するために使用されるモードで、stdio.h は次のモード定数を指定します。

SEEK_SET ファイルの先頭 
SEEK_CUR 現在位置 
SEEK_END ファイルの末尾

いくつかの呼び出し例を見てみましょう: 
 fseek(fp,0L,SEEK_SET); //ファイルの先頭を検索 
 fseek(fp,0L,SEEK_END); //ファイルの末尾まで検索 
 fseek(fp,2L,SEEK_CUR) ; //file 現在位置を 2 バイト進めます

ftell 関数はファイルの現在の場所を返すために使用され、戻り値の型は次の呼び出しのように long 型です。

fseek(fp,0L,SEEK_END);//最後まで検索 
        long last=ftell(fp); //現在位置を返す

そして、このときの最後は、ファイルポインタfpが指すファイルのバイト数となる。

標準 I/O と同様に、*nix システムは fseek の機能を完了するための lseek を提供します。プロトタイプは次のとおりです。

off_t lseek(int fildes, off_t offset, int whence);

fildes はファイル記述子であり、offset もオフセットであり、whence も指定された開始点モードです。唯一の違いは、lseek には戻り値があることです。成功した場合は、ポインタが変更される前の位置を返します。成功しなかった場合は、戻り値を返します。 -1。wherece の値は fseek と同じ (SEEK_SET、SEEK_CUR、SEEK_END) ですが、整数 0、1、2 に置き換えることもできます。

 

4. システムコールとライブラリ関数

         上ではファイル I/O と標準 I/O の違いについて説明してきましたが、実際には、ファイル I/O はシステム コール、標準 I/O はライブラリ関数であると言えます。以下の図を参照してください。

 

POSIX: ポータブル オペレーティング システム インターフェイス ポータブル オペレーティング システム インターフェイス

ANSI: American National Standardrads Institute アメリカ国家規格協会

1. システムコール

       オペレーティング システムは、すべてのコンピュータ リソースの管理と割り当てを担当します。アプリケーションをより適切に提供するために、オペレーティング システムは一連の特別なインターフェイス、つまりシステム コールを提供します。ユーザープログラムは、このインターフェース群を介して、オペレーティングシステムのカーネルが提供するさまざまな機能を利用できます。たとえば、メモリの割り当て、プロセスの作成、プロセス間の通信の実現などです。

       プログラムがコンピュータ リソースに直接アクセスできないのはなぜですか? 答えは安全ではありません。シングルチップマイコンの開発では、オペレーティングシステムが不要なため、開発者はハードウェアに直接アクセスするコードを書くことができます。32 ビット組み込みシステムでは、通常、オペレーティング システムが実行されているため、開発者はハードウェアに直接アクセスするコードを作成できます。32 ビット組み込みシステムでは、通常、オペレーティング システムが実行され、プログラムがリソースにアクセスする方法が変化しました。オペレーティング システムは基本的にマルチタスクをサポートしています。つまり、複数のプログラムを同時に実行できます。プログラムがシステム リソースに直接アクセスできるようにすると、間違いなく多くの問題が発生します。したがって、すべてのハードウェアおよびソフトウェア リソースの管理と割り当ては、オペレーティング システムの責任になります。プログラムはリソースを取得する必要があります (メモリの割り当て、シリアル ポートの読み書きなど) はオペレーティング システムによって完了する必要があります。つまり、ユーザー プログラムはオペレーティング システムにサービス要求を送信し、オペレーティング システムは関連するコードを実行して、リクエストを受け取った後の処理。

       ユーザー プログラムがオペレーティング システムに要求を行うためのインターフェイスはシステム コールです。すべてのオペレーティング システムはシステム コール インターフェイスを提供しますが、オペレーティング システムが異なれば提供するシステム コール インターフェイスも異なります。Linux システム コール インターフェイスは非常に合理化されており、Unix システム コールの最も基本的で便利な部分を継承しています。これらのシステムコールは、その機能に応じてプロセス制御、プロセス間通信、ファイルシステム制御、ストレージ管理、ネットワーク管理、ソケット制御、ユーザー管理などに大別されます。

2. ライブラリ関数

      システム コールは Linux や Windows などのオペレーティング システムに対するものであるため、ライブラリ関数はシステム コールの一種のカプセル化であると言えます。システム コールを直接作成すると、システム コールの移植性に影響を与えます。プログラムなので、ここではライブラリ関数が使用されます。たとえば、C ライブラリなので、C ライブラリがシステムにインストールされている限り、printf() scanf() などの関数を使用できます。 library はシステム関数を変換することと同等なので、APP はこれらの関数を呼び出すことができます。

3. ユーザープログラミングインターフェースAPI

     前述したように、システムコールインターフェースを利用したプログラムはさまざまなリソースにアクセスできますが、実際の開発ではシステムコールインターフェースを直接利用するのではなく、ユーザープログラミングインターフェース(API)を利用しますシステムコールインターフェースを直接使用しないのはなぜでしょうか?

その理由は次のとおりです。

1) システムコールインターフェースの機能は非常に単純であり、プログラムのニーズを満たすことができません。

2)異なるオペレーティングシステムのシステムコールインターフェースに互換性がなく、プログラム移植の負担が大きい。

    ユーザー プログラミング インターフェイスの一般的な説明は、さまざまなライブラリ (最も重要なのは C ライブラリ) の関数です。開発効率を向上させるために、Cライブラリには多くの機能が実装されています。これらの関数は、プログラマが呼び出す共通関数を実装します。これにより、プログラマはこれらのコードを自分で記述する必要がなく、ライブラリ関数を直接呼び出して基本的な機能を実現できるため、コードの再利用率が向上します。ユーザー プログラミング インターフェイスを使用することにはもう 1 つの利点があります。それは、プログラムの移植性に優れていることです。C ライブラリはほぼすべてのオペレーティング システムに実装されているため、通常、プログラムを再コンパイルするだけで他のオペレーティング システムで実行できます。

    ユーザー プログラミング インターフェイス (API) が実装される場合、通常はシステム コール インターフェイスに依存します。たとえば、プロセスを作成する API 関数 fork() は、カーネル空間の sys_fork() システム コールに対応します。多くの API 関数は、複数のシステム コールを通じてその機能を実行します。システムコールを一切呼び出さない API 関数もあります。

     Linux のユーザー プログラミング インターフェイス (API) は、Unix で最も一般的なアプリケーション プログラミング インターフェイス標準である POSIX 標準に従っています。POSIX 標準は、IEEE と ISO/IEC が共同開発した標準システムです。この標準は、当時意図されていた Unix の実践と経験に基づいて、アプリケーションがさまざまなオペレーティング システム上でソース コード レベルで実行できることを保証するために、オペレーティング システムのシステム コール プログラミング インターフェイス (実際には API) を記述しています。これらのシステム コール プログラミング インターフェイスは、主に C ライブラリ (libc) を通じて実現されます。


まず、ファイル I/O と標準 I/O とは何かを理解しましょう。

ファイル I/O:ファイル I/O は、キャッシュを使用しない IO (バッファなし I/O) と呼ばれます。キャッシュがないということは、すべての読み取りと書き込みがカーネル内のシステム コールを呼び出すことを意味します。これは一般に、低レベル I/O と呼ばれます。オペレーティング システムによって提供され、OS にバインドされ、Linux または UNIX プラットフォームに固有の基本的な I/O サービスです。

標準 I/O:標準 I/O は、ANSI C で定められた標準 I/O モデルで、標準機能パッケージと stdio.h ヘッダ ファイルで定義されており、一定の移植性があります。標準 I/O ライブラリは、詳細の多くを処理します。キャッシュの割り当て、最適化された長さでの I/O の実行など。標準 I/O は 3 種類のバッファを提供します。

(1) キャッシュがいっぱい: 実際の I/O 操作は、標準 I/O キャッシュがいっぱいになった後にのみ実行されます。 
(2) 行バッファ: 入力または出力で改行文字が出現すると、標準 I/O ライブラリが I/O 操作を実行します。 
(3) キャッシュなし: stderr で十分です。

第二に、両者の違いは、

      ファイル I/O は 、低レベル ディスク I/O とも呼ばれ、POSIX 関連の標準に従います。ファイル I/O は、POSIX 準拠のオペレーティング システムでサポートされています。標準 I/Oはアドバンスト ディスク I/O と呼ばれ、ANSI C 関連の規格に従います。標準 I/O は、開発環境で標準 I/O ライブラリが利用可能であれば使用できます。(GLIBC は、標準 C ライブラリのスーパーセットである Linux で使用されます。GLIBC には、ANSI C で定義された関数だけでなく、POSIX 標準で定義された関数も含まれています。したがって、標準 I/O とファイル I/O の両方が含まれます)。

      ファイル I/O を通じてファイルを読み書きする場合、各操作で関連するシステム コールが実行されます。このアプローチの利点は、実際のファイルを直接読み書きできることです。欠点は、頻繁なシステム コールによりシステムのオーバーヘッドが増加することです。標準 I/O は、ファイル I/O に基づいてカプセル化されたバッファ メカニズムとみなすことができます。最初にバッファの読み取りと書き込みが行われ、必要に応じて実際のファイルにアクセスするため、システム コールの数が削減されます。

      ファイル I/O では、ファイル記述子は開いているファイルを表すために使用され、通常のファイル、デバイス ファイル、パイプライン ファイルなどのさまざまな種類のファイルにアクセスできます。標準 I/O では、FILE (ストリーム) は開いているファイルを表すために使用されます。これは通常、通常のファイルにアクセスするためにのみ使用されます。

3. 最後に、使用する関数を確認します。

 

標準IO

ファイルIO(低レベルIO)

開ける

fopen、freopen、fdopen

開ける

閉鎖

f閉じる

近い

読む

getc、fgetc、getchar
fgets、
freadを取得

読む

書く

putc、fputc、putchar
fputs、puts、
fwrite

書く

1.fopen与open

標準 I/O は、 fopen 関数を使用してファイルを開きます。

FILE* fp=fopen(const char* パス,const char *mod)

path はファイル名で、mod は「r」、「w」、「w+」、「a」などのファイルを開くモードの文字列を指定するために使用されます。文字 b を追加して開くことを指定できます。バイナリ モード (*nix システムの場合、ファイル タイプは 1 つだけであるため、違いはありません) では、ファイルが正常に開かれた場合は FILE ファイル ポインタが返され、失敗した場合は NULL が返されます。実際のファイルを指すのではなく、ファイル情報パッケージに関するデータを指します。これには、ファイルによって使用されるバッファー情報が含まれます。

ファイル IO は、open 関数を使用してファイルを開きます。

int fd=open(char *name,int how);

fopen と同様に、name はファイル名の文字列を表し、オープン モードを指定する方法: O_RDONLY (読み取り専用)、O_WRONLY (書き込み専用)、O_RDWR (読み取りおよび書き込み可能)、およびその他のモードを指定します。man 2 open してください。正の整数を返すことに成功した場合はファイル記述子と呼ばれますが、これは標準 I/O とは大きく異なります。失敗した場合に -1 を返すことも、NULL を返す標準 I/O とは異なります。

2.f閉じると閉じる

ファイルを開くのとは対照的に、標準 I/O は fclose を使用してファイルを閉じ、ファイル ポインタを渡すだけです。正常に閉じられた場合は 0 を返し、そうでない場合は EOF を返します。次に例を示します

if(fclose(fp)!=0)  
            printf("ファイルを閉じる際のエラー");

ファイル IO は、open によって開かれたファイルを閉じるために close を使用します。これは fclose と似ていますが、エラーが発生した場合に EOF の代わりに -1 が返され、正常に閉じられた場合にも 0 が返される点が異なります。C 言語では、エラー処理にエラー コードを使用します。

3. ファイルgetc、fscanf、fgets を読み取り、読み取ります

標準 I/O でのファイル読み取りの場合、getc を使用して文字ごとに読み取ることも、gets (標準 io 読み取りの読み取り)、fgets を使用して文字列単位で読み取ることもできます (改行文字の後に最初に見つかったものまで読み取ります)。 (パラメーター、ファイル ポインターを受け入れます) は、ターゲット配列が読み取られた文字を収容できるかどうかを判断しません。これにより、ストレージ オーバーフローが発生する可能性があります (推奨されません)。 fgets は 3 つのパラメーターを使用します: char * fgets ( char *s、int size、
FILE *ストリーム);

最初のパラメータは gets と同じで、入力アドレスを格納するために使用されます。2 番目のパラメータは入力文字列の最大長を示す整数で、最後のパラメータは読み取られるファイルを指すファイル ポインタです。最後の fscanf は、scanf に似ていますが、fscanf(fp,"%s",words) など、操作するファイルを指定するパラメーターが追加され、ファイル IO で読み取り関数が使用されて読み取ります。 open 関数で開いたファイル、
関数 プロトタイプは次のとおりです。

ssize_t numread=read(int fd,void *buf,size_t qty);

このうち、fd は open によって返されるファイル記述子、buf はデータの目的のバッファを格納するために使用され、qty は読み取られるバイト数を指定します。正常に読み取られた場合は、読み取られたバイト数 (qty 以下) を返します。

4. ファイルの終わりを確認する

標準 IO の getc は、読み取り試行がファイルの終わりに達すると特別な値 EOF を返します。一方、fgets は EOF に遭遇すると NULL を返しますが、*nix 読み取り関数の場合は状況が異なります。read は qty で指定されたバイト数を読み込みますが、最終的に読み出したデータは要求した量 (qty) に満たない可能性があり、最後まで読んでから読みたい場合、read 関数は 0 を返します。

5. ファイルの書き込み: putc、fputs、fprintf、write

ファイルの読み取りに対応して、標準 C 言語 I/O は putc を使用して次のような文字を書き込みます。

putc ( ch , fp );

最初の引数は文字で、2 番目の引数はファイル ポインタです。fputs は次のようになります。

fputs(buf,fp);

最初のパラメータのみが文字列アドレスに置き換えられます。fprintf は printf に似ていますが、書き込むファイルを指定するパラメーターを追加します。次に例を示します。

fprintf(stdout,"こんにちは %s。\n","デニス");

fscanf と fprintf は最初のパラメータとして FILE ポインタを受け取り、putc と fputs は 2 番目のパラメータを取ることに注意してください。

ファイルを書き込むためのファイル IO には書き込み関数が提供されており、プロトタイプは読み取りに似ています。

ssize_t result=write(int fd,void *buf ,size_t amt);

fd はファイル記述子、buf は書き込まれるメモリ データ、amt は書き込まれるバイト数です。書き込みが成功した場合は書き込んだバイト数を返し、その結果をamtと比較することで書き込みが正常かどうかを判断できます 書き込みに失敗した場合は-1を返します

6. ランダムアクセス: fseek()、ftell()、lseek()

標準 I/O はファイルへのランダム アクセスに fseek と ftell を使用します。まず fseek 関数のプロトタイプを見てください。

int fseek(FILE *stream, long offset, int wherece);

第一引数はファイルポインタ、第二引数は始点からの移動距離を示すlong型のオフセット(offset)です。3 番目のパラメーターは開始点を指定するために使用されるモードで、stdio.h は次のモード定数を指定します。

SEEK_SET ファイルの先頭 
SEEK_CUR 現在位置 
SEEK_END ファイルの末尾

いくつかの呼び出し例を見てみましょう: 
 fseek(fp,0L,SEEK_SET); //ファイルの先頭を検索 
 fseek(fp,0L,SEEK_END); //ファイルの末尾まで検索 
 fseek(fp,2L,SEEK_CUR) ; //file 現在位置を 2 バイト進めます

ftell 関数はファイルの現在の場所を返すために使用され、戻り値の型は次の呼び出しのように long 型です。

fseek(fp,0L,SEEK_END);//最後まで検索 
        long last=ftell(fp); //現在位置を返す

そして、このときの最後は、ファイルポインタfpが指すファイルのバイト数となる。

標準 I/O と同様に、*nix システムは fseek の機能を完了するための lseek を提供します。プロトタイプは次のとおりです。

off_t lseek(int fildes, off_t offset, int whence);

fildes はファイル記述子であり、offset もオフセットであり、whence も指定された開始点モードです。唯一の違いは、lseek には戻り値があることです。成功した場合は、ポインタが変更される前の位置を返します。成功しなかった場合は、戻り値を返します。 -1。wherece の値は fseek と同じ (SEEK_SET、SEEK_CUR、SEEK_END) ですが、整数 0、1、2 に置き換えることもできます。

 

4. システムコールとライブラリ関数

         上ではファイル I/O と標準 I/O の違いについて説明してきましたが、実際には、ファイル I/O はシステム コール、標準 I/O はライブラリ関数であると言えます。以下の図を参照してください。

 

POSIX: ポータブル オペレーティング システム インターフェイス ポータブル オペレーティング システム インターフェイス

ANSI: American National Standardrads Institute アメリカ国家規格協会

1. システムコール

       オペレーティング システムは、すべてのコンピュータ リソースの管理と割り当てを担当します。アプリケーションをより適切に提供するために、オペレーティング システムは一連の特別なインターフェイス、つまりシステム コールを提供します。ユーザープログラムは、このインターフェース群を介して、オペレーティングシステムのカーネルが提供するさまざまな機能を利用できます。たとえば、メモリの割り当て、プロセスの作成、プロセス間の通信の実現などです。

       プログラムがコンピュータ リソースに直接アクセスできないのはなぜですか? 答えは安全ではありません。シングルチップマイコンの開発では、オペレーティングシステムが不要なため、開発者はハードウェアに直接アクセスするコードを書くことができます。32 ビット組み込みシステムでは、通常、オペレーティング システムが実行されているため、開発者はハードウェアに直接アクセスするコードを作成できます。32 ビット組み込みシステムでは、通常、オペレーティング システムが実行され、プログラムがリソースにアクセスする方法が変化しました。オペレーティング システムは基本的にマルチタスクをサポートしています。つまり、複数のプログラムを同時に実行できます。プログラムがシステム リソースに直接アクセスできるようにすると、間違いなく多くの問題が発生します。したがって、すべてのハードウェアおよびソフトウェア リソースの管理と割り当ては、オペレーティング システムの責任になります。プログラムはリソースを取得する必要があります (メモリの割り当て、シリアル ポートの読み書きなど) はオペレーティング システムによって完了する必要があります。つまり、ユーザー プログラムはオペレーティング システムにサービス要求を送信し、オペレーティング システムは関連するコードを実行して、リクエストを受け取った後の処理。

       ユーザー プログラムがオペレーティング システムに要求を行うためのインターフェイスはシステム コールです。すべてのオペレーティング システムはシステム コール インターフェイスを提供しますが、オペレーティング システムが異なれば提供するシステム コール インターフェイスも異なります。Linux システム コール インターフェイスは非常に合理化されており、Unix システム コールの最も基本的で便利な部分を継承しています。これらのシステムコールは、その機能に応じてプロセス制御、プロセス間通信、ファイルシステム制御、ストレージ管理、ネットワーク管理、ソケット制御、ユーザー管理などに大別されます。

2. ライブラリ関数

      システム コールは Linux や Windows などのオペレーティング システムに対するものであるため、ライブラリ関数はシステム コールの一種のカプセル化であると言えます。システム コールを直接作成すると、システム コールの移植性に影響を与えます。プログラムなので、ここではライブラリ関数が使用されます。たとえば、C ライブラリなので、C ライブラリがシステムにインストールされている限り、printf() scanf() などの関数を使用できます。 library はシステム関数を変換することと同等なので、APP はこれらの関数を呼び出すことができます。

3. ユーザープログラミングインターフェースAPI

     前述したように、システムコールインターフェースを利用したプログラムはさまざまなリソースにアクセスできますが、実際の開発ではシステムコールインターフェースを直接利用するのではなく、ユーザープログラミングインターフェース(API)を利用しますシステムコールインターフェースを直接使用しないのはなぜでしょうか?

その理由は次のとおりです。

1) システムコールインターフェースの機能は非常に単純であり、プログラムのニーズを満たすことができません。

2)異なるオペレーティングシステムのシステムコールインターフェースに互換性がなく、プログラム移植の負担が大きい。

    ユーザー プログラミング インターフェイスの一般的な説明は、さまざまなライブラリ (最も重要なのは C ライブラリ) の関数です。開発効率を向上させるために、Cライブラリには多くの機能が実装されています。これらの関数は、プログラマが呼び出す共通関数を実装します。これにより、プログラマはこれらのコードを自分で記述する必要がなく、ライブラリ関数を直接呼び出して基本的な機能を実現できるため、コードの再利用率が向上します。ユーザー プログラミング インターフェイスを使用することにはもう 1 つの利点があります。それは、プログラムの移植性に優れていることです。C ライブラリはほぼすべてのオペレーティング システムに実装されているため、通常、プログラムを再コンパイルするだけで他のオペレーティング システムで実行できます。

    ユーザー プログラミング インターフェイス (API) が実装される場合、通常はシステム コール インターフェイスに依存します。たとえば、プロセスを作成する API 関数 fork() は、カーネル空間の sys_fork() システム コールに対応します。多くの API 関数は、複数のシステム コールを通じてその機能を実行します。システムコールを一切呼び出さない API 関数もあります。

     Linux のユーザー プログラミング インターフェイス (API) は、Unix で最も一般的なアプリケーション プログラミング インターフェイス標準である POSIX 標準に従っています。POSIX 標準は、IEEE と ISO/IEC が共同開発した標準システムです。この標準は、当時意図されていた Unix の実践と経験に基づいて、アプリケーションがさまざまなオペレーティング システム上でソース コード レベルで実行できることを保証するために、オペレーティング システムのシステム コール プログラミング インターフェイス (実際には API) を記述しています。これらのシステム コール プログラミング インターフェイスは、主に C ライブラリ (libc) を通じて実現されます。


おすすめ

転載: blog.csdn.net/psq1508690245/article/details/115205191