この記事の内容は、Linux でのいくつかのファイルの種類を紹介することです。必要な方は参考にしていただければ幸いです。 [ビデオチュートリアルの推奨: Linux チュートリアル ]
Linux システムでは、次の 7 種類のファイルがあります。
通常のファイル ( - )
パイプ ファイル
に分割されます。パイプは一方の端で書き込まれ、もう一方の端で読み取られます。これらは一方向のデータ送信であり、パイプは親プロセスの書き込みや子プロセスの読み取りなどのプロセス間通信の方法です。 。 シェルでは、匿名パイプはパイプ記号「|」です (
ls | grep xxx など)。ls に対応するプロセスは、この独立したプロセス グループの親プロセスです。と grep に対応するプロセス 子プロセスです。親プロセスは書き込み、子プロセスは読み取りを行います。 プログラミング言語では、匿名パイプは 2 つのファイル ハンドルまたはファイル記述子 (A、B など) を作成することによって実装されます (A 書き込み終了、データ書き込み終了など)。自動的にそれを B) にプッシュし、別のファイル ハンドルを使用してデータ (つまり B) を読み取ります。
名前付きパイプ、つまり名前付きパイプの場合、名前付きパイプはファイル システムにファイルを保持します。これは先入れ先出しを意味する FIFO とも呼ばれます。名前付きパイプ ファイルはファイル システムに保持されますが、このファイルは名前付きパイプを使用するためのエントリ ポイントにすぎず、名前付きパイプを使用してデータを送信する場合もメモリ内で実行されます。つまり、名前付きパイプはメモリ上に保持されません。名前付きパイプは効率が低くなります。
シェルでは、
mknod コマンドまたは mkfifo
コマンドを使用して名前付きパイプを作成できます。名前付きパイプは、特定の特殊なシェル スクリプトを作成するときに非常に便利です。ニーズ。実際、コルーチンの機能 (coproc コマンドを使用) は Bash 4 以降サポートされています (ksh と zsh は長い間コルーチンをサポートしていました)。しかし、コルーチンのニーズは名前付きパイプを通じて実現できます。 一般的なパイプラインは一方向通信であり、双方向通信の機能を実現できません。つまり、同時に書き込みと読み取りのみが可能で、両側での読み取りと書き込みはできません。双方向通信を実現したい場合は、2 つのパイプ (つまり、4 つのファイル ハンドル、2 つの読み取り端、2 つの書き込み端がある) を作成するか、より便利なソケットを使用できます。
ソケット
ソケットは意味を持たせるためにペアにする必要があります。つまり、ソケットは 2 つの端に分かれており、それぞれの端に読み取りと書き込みのためのファイル記述子 (またはファイル ハンドル) があり、これは 2 つの双方向通信に相当します。パイプ。
ソケットは、プロトコル ファミリに従って、ネットワーク ソケット (AF_INET タイプ、ipv4 と ipv6 に従って inet4 と inet6 に分割) と Unix ドメイン ソケット (AF_UNIX タイプ) の 2 つのカテゴリに分類されます。もちろん、ソケットはプロトコル ファミリからさらに多くのタイプに細分化できます。たとえば、INET ソケットは、TCP ソケット、UDP ソケット、リンク層ソケット、Raw ソケットなどに分類できます。その中でも、ネットワーク ソケットはネットワーク プログラミングの基礎であり、中核です。
Unix ドメイン ソケット
Unix ドメイン ソケットには 2 つのファイル ハンドル (A、B など) があり、両方のファイル ハンドルは同時に読み取り可能であり、書き込み可能です。プロセス 1 がデータを A に書き込むと、そのデータは自動的に B にプッシュされます。プロセス 2 は、A から書き込まれたデータを B から読み取ることができます。同様に、プロセス 2 がデータを B に書き込むと、自動的に A にプッシュされます。プロセス 1 は読み取りができますB から A に書き込まれたデータ。以下のように:
进程1 进程2 ------------------------ A -----------> B B -----------> A
プログラミング言語では、Unix ドメイン ソケットの作成には、当然のことながら、それを簡単に作成するための対応する関数があります (
manソケットペアが可能)。 bash シェルの場合は、nc
コマンド (NetCat) を使用して作成するか、単純に 2 つの名前付きパイプを使用して対応する関数を実装できます。必要に応じて、bash シェルで Unix ドメイン ソケットを使用する方法を学ぶことができます。 ネットワーク ソケット
{protocol, src_addr, src_port, dest_addr, dest_port}
つまり、プロトコル、送信元アドレス、送信元ポート、宛先アドレス、および宛先ポート。
ソケットの各エンドにはカーネル空間に 2 つのバッファーがあり (つまり、1 組のソケットには 4 つのバッファーがあります)、各エンドには受信バッファーと送信バッファーがあります。プロセス 1 は、自身のソケットの送信バッファにデータを書き込み、そのデータはピアの受信バッファに送信され、ピアのプロセス 2 は受信バッファからデータを読み取ることができ、その逆も同様です。
ただし、実際にネットワーク ソケットの読み取りと書き込みを行う前に、ネットワーク ソケットにいくつかの設定が必要です。サーバーソケットが作成された後 (socket() 関数、読み取りおよび書き込み操作のためのファイルハンドルまたはファイル記述子が存在します)、アドレス (bind() 関数を介して) とリスニングポート (listen() を介して) もバインドする必要があります。 ) 関数)、クライアントはソケットを作成し、connect() 関数を直接使用してサーバーソケットへの接続リクエストを開始するだけで済みます。
TCP ソケットの場合、クライアントが接続要求を開始するとき、それはサーバーとの 3 ウェイ ハンドシェイクを実行する必要があることを意味します (カーネルによって完了され、ユーザー空間プロセスとは何の関係もありません)。これら 3 つのハンドシェイクをそれぞれ詳しく説明します。クライアントが初めて SYN 要求を送信したとき、サーバーが SYN を受信した後、カーネルは接続を syn キューに入れ、ステータスを syn-recv に設定し、ack syn をサーバーに送信します。一方、クライアントの応答 ack を受信した後、カーネルは接続を syn キューから確立されたキュー (または受け入れキュー) に移動し、接続のステータスを確立済みとしてマークします。最後に、ユーザー空間を待機しているプロセスは、accept() システム コールを開始して、カーネルに受け入れキューからユーザー空間を削除させます。 accept()後の接続は接続が確立したことを示しており、真に両端のプロセス間のデータ送信が実現できます。
TCP ソケットの原理の詳細については、私の別の記事「知っておくべきソケットと TCP 接続プロセス」を参照してください。
ブロック デバイスは、固定サイズのデータ チャンクへのランダム (必ずしも順次ではない) アクセスによって区別されるハードウェア デバイスです。固定サイズのチャンクはブロックと呼ばれます。 最も一般的なブロック デバイスはハードディスクですですが、フロッピー ドライブ、Blu-ray リーダー、フラッシュ メモリなど、他にも多くのブロック デバイスが存在します。これらはファイル システムがマウントされているデバイスであり、ファイル システムはブロック デバイスの共通語のようなものであることに注意してください。
キャラクタ デバイスは、バイトごとに連続したデータ ストリームを通じてアクセスされます。 典型的なキャラクター デバイスは、端末 (物理端末と仮想端末の両方でさまざまな種類の端末があります) とキーボード です。
ブロック デバイスとキャラクター デバイスを区別する最も簡単な方法は、データへのアクセス方法に注目することです。ブロック デバイスはデータを取得するためにランダムにアクセスできますが、キャラクタ デバイスはバイト オーダー でアクセスする必要があります。
ここで少しのデータを読み取り、そこから少しのデータを読み取り、最終的にそれを連続したデータにつなげることができる場合、これは、ハードディスク上のデータが不連続であるのと同じように、ブロック デバイスです。データを取得するには、ランダム アクセス方式でアクセスする必要がある場合があります。たとえば、ディスク上の少し大きなファイルでは、最初の 10,000 個のデータが連続したデータ ブロックまたは連続したセクターに存在し、次の 10,000 個のデータがそこから遠く離れているか、異なるシリンダー上にある可能性があります。
データ内の各バイトがアクセス時と同じバイト順序である場合、つまり、バイト順序がアクセス時からデータの最終処理まで完全に一貫している場合、これはキャラクターデバイス。つまり、キャラクター デバイスはストリーム デバイスと考えることができます。キーボードでデータを入力するのと同じように、2 つのキーを連続して押した場合、これら 2 つのキーに対応するバイト データを受信したときに、最初に前に入力し、次に後ろに入力する必要があります。同様に、端末デバイスも同様に動作します。プログラムが端末にデータを出力するとき、プログラムは最初に文字 a を出力し、次に数字の 3 を出力します。その後、端末に表示されるときは、a が前にあり、3 が後ろにある必要があります。後ろ。
以上がLinux でのファイル タイプの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。