Linux標準IOとファイルIOの違いと接続

序文:

      この記事の主な内容はインターネットから抽出されたもので、見つかった散在した情報は要約され、後で参照できるようにまとめられます。

      次の記事を参照してください。共有していただきありがとうございます。

      Linux Quest I / O効率

      https://cloud.tencent.com/developer/article/1018033

      Linuxシステムプログラミングの基本(4):C標準ライブラリのIOバッファーとカーネルバッファーの違い     

      https://cloud.tencent.com/developer/article/1012299

概念:


       標準I / O:標準I / Oライブラリを指します。バッファ付きI / Oとも呼ばれます。これはANSI C標準で規定されています。標準I / Oライブラリは、ユーザーに代わって、キャッシュ割り当て、最適化された長さでのI / O実行など、多くの詳細を処理します。キャッシュを提供する目的は、読み取りおよび書き込み呼び出しの数を最小限に抑えることです。
一般的な関数:fopen、fread、fwrite、fclose、printf、fprintf、scanf、sscanfなど。
ファイルI / O:アンバッファードI / Oとも呼ばれ、読み取りと書き込みはそれぞれカーネル内のシステムコールです。これらのバッファリングされていないファイルI / O関数は、ISO Cの一部ではありません。これらはPOSIX.1およびSingle UNIX Specificationの一部です。一般的な機能:開く、読み取り、書き込み、lseek、閉じるなど。

連絡先:


      ユーザープログラムはC標準I / Oライブラリー関数を呼び出して通常のファイルまたはデバイスを読み書きし、これらのライブラリー関数はシステムコールを通じて読み取りおよび書き込み要求をカーネルに渡し、カーネルはディスクまたはデバイスを駆動してI / O操作を完了します。C標準ライブラリは、開いている各ファイルにI / Oバッファーを割り当てて、読み取りおよび書き込み操作を高速化します。このバッファーは、ファイルのFILE構造を介して見つけることができます。ユーザーは、ほとんどの場合、I / Oバッファーで読み取りおよび書き込み関数を呼び出します。読み取りと書き込み。ほんの数回は、読み取りと書き込み要求をカーネルに渡す必要があります。fgetc / fputcを例にとると、ユーザープログラムが初めてfgetcを呼び出してバイトを読み取る場合、fgetc関数はシステムコールを介してカーネルに入り、1KバイトをI / Oバッファーに読み込んでから、I / Oバッファーに値を返します。最初のバイトはユーザーに与えられ、読み取りおよび書き込み位置はI / Oバッファーの2番目の文字を指します。その後、ユーザーはfgetcを調整し、カーネルに入らずにI / Oバッファーから直接読み取ります。ユーザーがすべての1Kバイトの読み取りを完了し、fgetcを再度呼び出すと、fgetc関数はカーネルに再び入り、1KバイトをI / Oバッファーに読み取ります。このシナリオでは、ユーザープログラム、C標準ライブラリ、およびカーネル間の関係は、「メモリ階層」のCPU、キャッシュ、およびメモリ間の関係と同じです。C標準ライブラリがカーネルから一部のデータを先読みする理由は、 / Oバッファーでは、ユーザープログラムが後でこれらのデータを使用することが望まれます。C標準ライブラリのI / Oバッファーもユーザー空間にあります。ユーザー空間から直接データを読み取る方が、カーネルにデータを読み取るよりもはるかに高速です。一方、fputcを呼び出すユーザープログラムは通常、I / Oバッファーにのみ書き込まれるため、fputc関数はすばやく戻ることができます。I/ Oバッファーがいっぱいになると、fputcはI / Oバッファーをシステムコールに入れます。データはカーネルに渡され、カーネルは最終的にデータをディスクまたはデバイスに書き戻します。ユーザープログラムがI / Oバッファー内のデータをすぐにカーネルに転送して、カーネルがデバイスまたはディスクにデータを書き戻したい場合があります。これは、フラッシュ操作と呼ばれます。対応するライブラリ関数はfflushです。fclose関数は、ファイルを閉じる前にフラッシュも実行します。オペレーティング。


違い:


1.バッファリングメカニズムの違い:
      ご存じのとおり、CPUとメモリのデータ交換はディスク操作よりもはるかに大きくなります。キャッシングメカニズムにより、ディスクの読み取りと書き込みの数を減らし、並行処理プログラムの効率を向上させることができます。したがって、キャッシュはタスクのストレージと処理を改善する方法です。効率の効果的な方法。
マクロの観点から見ると、Linuxオペレーティングシステムはユーザーモードとカーネルモードに分かれており、どちらもI / O操作の処理時にキャッシュを提供します。ユーザーモードは標準I / Oキャッシュと呼ばれ、ユーザースペースキャッシュとも呼ばれ、カーネルモードはバッファーキャッシュと呼ばれ、ページキャッシュとも呼ばれます。キャッシュが提供されているため、この本がI / OなしのキャッシュとI / O付きのキャッシュに分かれている理由。「I / Oキャッシュなし」は、これらのI / Oがユーザー空間で使用できないことを意味します。 / O操作はバッファーに入れられ、カーネルはバッファーに入れられます。

2. I / O操作のフローの違い:


  上の図に示すように、ユーザープロセススペースとカーネルプロセススペースの読み取りおよび書き込み操作は、バッファーキャッシュを経由する必要があります。キャッシュの機能についても前述したので、ディスクの読み取りと書き込みの数を減らし、I / Oの効率を向上させています。ファイルを読み書きするときは、まずシステムI / Oの操作の流れを見てください。
2.1ファイルI / O:

これはカーネルシステムコールに属し、ユーザーモードの参加を含みません。図のラベルを例にとると:
      (3)write関数を呼び出してデータをファイルに書き込み、書き込むデータはwrite(fd、 'abc'、3)などのbufに格納されます。呼び出す前にBUFFSIZEを設定する必要があります。異なるBUFFSIZEはI / O効率に影響します。この問題についてもう一度話しましょう。
      (5)遅延書き込み:キャッシュ領域がいっぱいになった場合、またはカーネルがバッファーを再書き込みする必要がある場合、データは出力キューに書き込まれ、データがキューの先頭に到達すると、ディスク書き込み操作が実際にトリガーされます。
      (6)事前読み取り:順次読み取りが実行されていることを検出すると、カーネルはアプリケーションが必要とするよりも多くのデータを読み取ろうとし、アプリケーションがこれらのデータをすぐに読み取ると想定します。このようにして、バッファにデータがない場合、次に読み込まれるデータをすばやく満たすことができます。
      (4)readを呼び出して、必要なデータをバッファキャッシュからロジックユニットに読み込んで処理します。
上記は、システムI / Oに関連する4つのステップの操作です。

2.2標準I / O:

      これは、ISO Cによって実装された標準ライブラリ関数に属し、基になるシステムコールを呼び出します。
      (1)論理ユニットのデータをファイルに書き込む。必要に応じて、呼び出すことができる関数には3つのタイプがあります。例として、fputc、fputs、およびfwriteを使用します。これらの関数は、バッファーのサイズを人為的に制御する必要はありませんが、システムによって自動的に適用されます。ユーザーが対応するI / O関数を定義すると、さまざまなキャッシュタイプ(フルバッファー、ラインバッファー、またはバッファーなし)に応じて、システムは自動的にmallocおよびその他の関数を呼び出してバッファー、つまり標準I / Oバッファーを適用します。
      (3)(5)システムI / O操作のようにユーザーバッファーがいっぱいになった場合は、この時点でwriteを呼び出して、標準I / Oバッファーからカーネルバッファーにデータをコピーしてから、ディスクに書き込みます。
      (4)(6)システムI / O操作と同様に、カーネルバッファーからreadを呼び出してユーザーバッファーに読み取ります。
      (2)呼び出すことができる関数は3種類あり、fgetc、fgets、およびfreadを例にとると、その後の処理のために論理ユニットに読み込まれます。
標準I / Oの実装メカニズムはシステムI / Oに基づいていることがわかります。このように、標準I / OはシステムI / Oほど効率的ではありませんが、標準I / OはシステムI / Oと比較されていません。それははるかに遅いです、そして他の多くの利点があります。

2.3データフローを使用して2つの違いを説明する:
      非バッファーI / O操作の
      データフロー:データ->カーネルバッファー->ディスク標準I / O操作のデータフロー:データ->ストリームバッファー->カーネルバッファー->ディスク

2.4標準I / Oの利点と欠点:
      1)標準I / Oルーチンを使用する利点の1つは、キャッシュの選択と最適なI / O長を考慮する必要がないことであり、読み取りと書き込みを直接呼び出すよりも遅くはありません
      。2)で標準I / Oライブラリでは、非効率的な欠点は、コピーする必要のあるデータの量です。関数fgetsとfputsを一度に1行ずつ使用する場合、通常はデータを2回コピーする必要があります。1回目はカーネルと標準I / Oキャッシュ間で(読み取りと書き込みを呼び出す場合)、2回目は標準I / Oキャッシュで(通常、システムはユーザープログラムのラインキャッシュを割り当てて管理します(fgetsのパラメーターにはユーザーラインキャッシュポインターが必要です)。

3.古典的な答え:
      前者は低レベルIO、後者は高レベルIOです。
      前者はファイル記述子(ユーザープログラム領域内)を返し、後者はファイルポインターを返します。
      前者にはバッファがなく、後者にはバッファがあります。
      前者は読み取りと書き込みと組み合わせて使用​​され、後者はfreadとfwriteと組み合わせて使用​​されます。
      後者は前者に基づいており、ほとんどの場合、後者が使用されます。
     上記は、openとfopenの違いの紹介です。2つの違いは、主にバッファリングの違いです。Fopenにはバッファリングがありますが、openにはありません。また、レベルも異なります。Fopenは移植可能ですが、openはできません。
 

おすすめ

転載: blog.csdn.net/the_wan/article/details/108309703
おすすめ