(理解することが考えホース付き)プロセス間通信パイプ

何事も後退ではありません。anghingは、それだけですべての.--------なし後退隣にある何のためにあなたのやる気を引き出す場合は、彼がどんな意味を持っている場合、それだけでより良いを実行するために、再度次の課題をあなたを刺激されます。

1、見通しレビュー

プロセス間の通信は、確かにブログを書かれている、または知識のこの分野に関心のある黒の人々の前に、プロセスに関連している生徒できることはほとんど錆び会場:

https://blog.csdn.net/weixin_46027505/article/details/104812719

https://blog.csdn.net/weixin_46027505/article/details/105141592

2、パイプは本当にパイプラインであります

  • 導入管の前に通信の3種類を見ることが必要です。

1、单工通信:传输方向只有一个方向,单工通信只有一根数据线,它也只在一个方向上进行,如打印机、电视机等。例えば:テレビ、ラジオ
2、半双工通信:可以双向通信,但只能轮流传输,也只有一根数据线,不同于单工通信的是这根数据线即可作为发送又可作为接收,虽数据可在两个方向上传送,但通信双方不能同时收发数据。ウォーキートーキー:のような
3、全双工通信:可以同时双向传输数据,数据的发送和接收用两根不同的数据线,通信双方在同一时刻都能进行发送和接收,发送和接收同时进行,没有延迟。ビデオチャットなど

2.1パイプラインの人気の理解

  • なぜ、この通信メカニズムは、パイプライン、それと呼ばれますか?その機能は、実際にパイプでの生活の役割があるので(水路)があります。

私たちは、水が私たちの間のデータ伝送プロセス間通信で、パイプラインがボトル入り飲料水に使用され、私たち自身の家が別のプロセス空間で、プロセス空間に比べて水の供給を入れ、配管内の水は、ファイルへの書き込みデータに相当する
必要パイプラインがされて、覚えている一方通行は、FIFOが、これは水のサプライヤーはあなたにボトル入り飲料水を提供するのと同様に、理解しやすいです、あなたはパイプに注入水をすることはできません。

2.2パイプラインは、半二重通信があるのはなぜ?

Linuxのコマンドの1つの機能のみを実行することができますので、それはより複雑なタスクは、いくつかの共同処理が完了している必要があり、その結果は、第二のプロセスに最初のプロセスに対処する必要があり、その後、第三に引き渡さ、というように、組立ラインのような時間のデザインは半二重を作ったので、完全な商品生産と同様に、このプロセスは、データの一方向のみの伝送をダウンかかります。
もちろん、また、2本のパイプを二重通信パイプを達成するために使用されます。

2.3パイプラインの機能

導管は別の処理へのその入力と出力に接続されています。

図1は、処理(書き込み処理)は、パイプラインの端部にヘッドパイプからデータを読み取るの別の処理(読出し処理)データを書き込みます。
パイプの端部は端部を読み書きするために固定されています。各バッファの内容を書き込むパイプの最後に追加され、各時間データは、バッファの先頭から読み出されます。

図2に示すように、データを処理した後に読み出され、パイプラインから削除され、他の読み出し処理は、データを読み取ることができません。

図3に示すように、パイプラインが空のパイプラインを読み取ろうとするプロセスは、プロセスがブロックされ、簡単なフロー制御メカニズムを提供します。同様に、パイプラインがすでにいっぱいで、その後、プロセス配管に書き込みデータにしよう、プロセスがブロックされます

図4に示すように、処理のために導管の両端は、ファイルであり、それは一般的なファイルではない、それは特定のファイルシステムに属しているが、自分でライブ、単一のファイルシステムを構成し、メモリ内にのみ存在しません。

5は、データがパイプラインに書き込まれ、Linuxは保証の原子が書かれていないだろう、パイプバッファの空き領域がある、書き込み処理は、パイプにデータを書き込むしようとします。読み取り処理は、読み取りデータパイプラインバッファを行っていない場合は、書き込み操作がブロックされます。

図6は、パイプのリード端が存在する場合にのみ、それはパイプへの書き込みデータに意味をなします。それ以外の場合は、カーネルを受けるパイプラインにデータを書き込むプロセスは、(デフォルトのアクションは、アプリケーションを終了することがある)信号を処理できるアプリケーションは、無視することができ、SIFPIPE信号が来ました。

  • もちろん、パイプの2種類があります。
    1、名前なしパイプ:だけ親と子のために使用することが、あなたは、あなたとあなたのお父さんの分離を理解することができ、これは、水の供給のあなたの2本のパイプのためです。パイプライン君とお父さんので
    2、名前付きパイプは:同じシステム、任意のプロセス間通信に使用することができます。

戻るすぐに導入。

3、名前パイプ(時々混同しないように、直接パイプラインと呼ばれます)

パイプラインは、UNIXシステムのIPCの最古の形態である、すべてのUNIXシステムは、通信機構を提供します。本質導管はFIFO(FIFO、先入れ先出し)の方法からのアクセスデータをバッファ処理するカーネルバッファである:パイプラインプロセスの一端が順次データを処理するためにバッファに書き込まれ、プロセスの他の端部であります順次円形キューバッファとして見ることができるデータを読み出し、読み出し及び書き込み位置が自動的に追加され、データは一度だけ読み出されると、バッファを読み取ることができなくなっています。バッファが空であるか読んで満たされている場合は、バッファが空のとき、プロセスが待ちキューに入るかどう対応する読み出しや書き込みプロセスを制御するために、一定のルールがあり、新しいデータが書き込まれたり、低速データは、目を覚ますのを待って、バッファから読み出されキュー・プロセスは、読み取りおよび書き込みを続けています。

3.1制限事項

(1)半二重は、データは、今いくつかのシステムは、全二重パイプをサポートすることができる、一方向に流れることができるが、最適な移植のために、全二重パイプをサポートしていないシステムを考慮すべきです。

(2)それが通信処理の間にパイプ名前親子関係のみを使用することができます。

#3は3.2無名のパイプを作成
、それが読み取り、書き込みも通常の読み出し、書き込みなどの機能を使用することができるため、パイプラインは、ファイルの特別な種類として見ることができます。しかし、それは他のファイルシステムに属していない、通常のファイルではなく、メモリ内にのみ存在します。
パイプの関数を呼び出すことにより、パイプラインが作成されます。

#include <unistd.h>
int pipe(int fd[2]); 
  • 戻り値:成功した場合、0を返し、エラーの場合、戻り値-1。
    パラメータFDを介して返さ二つのファイルディスクリプタ:
    FD [0]読み取り専用で開かれた(水道管に使用される)
    FDのみ[1] (水道管に使用される)書き込みのために開かれた
    FD出力[1] fdが[0]入力

図4に示すように、単一のプロセス間通信パイプ不明

実際には、パイプラインは、次のサンプルコードでは、自分のためであると読み出されたメッセージを送信、ファイルです。
ここに画像を挿入説明

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>


#define MSG "my name is xuxiaohei"

int main(int argc, char **argv)
{
    int     pipe_fd[1];
    int     rv;
    char    buf[512];


   
    if (pipe(pipe_fd) < 0)
    {
        printf("Create pipe failure: %s\n", strerror(errno));
        return -1;
    }

    memset(buf, 0, sizeof(buf));
        
    if (write(pipe_fd[1], MSG, strlen(MSG)) < 0)
    {
        printf(" write data to pipe failure: %s\n", strerror(errno));
        return -2;
    }
    
    rv = read(pipe_fd[0], buf, sizeof(buf));
    if (rv < 0)
    {
            printf(" read from pipe failure: %s\n", strerror(errno));
            return -3;
    }
    printf("process read %d bytes data from pipe: \"%s\"\n", rv, buf);

      

    return 0;
}

ここに画像を挿入説明

5、親と子のコミュニケーション無名のパイプを達成するために

次の書き込み親プロセスの子プロセス方向にデータを送信するためのルーチン。まず、パイプラインフォーク(後に作成された親プロセス)、そして子供が(パイプラインを含む)すべてのオープン・ファイル記述子の親を継承する、そして4は読み取りと書き込みの終了(親と子が読むためのパイプのペアと書き込みを持っているパイプラインのためにそこにあります終わり)あなたが書き込みデータへの子の内側に親プロセスが必要な場合は、あなたが子供で近い書き込み終了、親プロセスの読み取り終了を閉じる必要があり、そして親に書き込みデータに子を必要に応じて、あなたは親プロセスをオフにすることができます書き込み端子、および近い読み取り終了後、子プロセス。
ここに画像を挿入説明

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MSG_STR "This message is from father: Hello, my son!"

int main(int argc, char **argv)
{
    int     pipe_fd[1];
    int     rv;
    int     pid;
    char    buf[512];
    int     wstatus;

    printf("before creat pipe\n");
    if (pipe(pipe_fd) < 0)
    {
        printf("Create pipe failure: %s\n", strerror(errno));
        return -1;
    }


    printf("before fork\n");
    if ((pid = fork()) < 0)
    {
        printf("Create child process failure: %s\n", strerror(errno));
        return -2;
    }
    else if (pid == 0)
    {
        printf("son start read message from father\n");
        close(pipe_fd[1]);
        memset(buf, 0, sizeof(buf));
        rv = read(pipe_fd[0], buf, sizeof(buf));
        if (rv < 0)
        {
            printf("Child process read from pipe failure: %s\n", strerror(errno));
            return -3;
        }
        printf("Child process read %d bytes data from pipe: \"%s\"\n", rv, buf);
        return 0;
    }




    close(pipe_fd[0]);
    if (write(pipe_fd[1], MSG_STR, strlen(MSG_STR)) < 0)
    {
        printf("Parent process write data to pipe failure: %s\n", strerror(errno));
        return -3;
    }


    printf("father finish write and wait son read \n");
    wait(&wstatus);


    return 0;
}

パイプの一端閉鎖     
、すべてのデータが読み出された後、ライトパイプの端を読み取ること、閉じているとき(1)、ファイルの終了を示す0を返し、読み出され     
、リードライトパイプの端部が閉じられたとき(2)信号がまたはキャッチして、ハンドラからのリターン信号、wirteを-1無視すればSIGPIPEは、信号を生成します。

ここに画像を挿入説明

あなたは子プロセスにメッセージを送信したい場合は、親プロセスが
あります
ここに画像を挿入説明

図6に示すように、名前付きパイプFIFO(または名前付きパイプと呼ばれます)

もちろん、同じ名前付きパイプは、半二重です。

唯一の複数の通信に関連する2つのプロセス間の名前付きパイプの前で言及されていない、
(名前付きパイプ)名前付きパイプFIFOを介して、無関係なプロセスがデータを交換することができます。

これは、FIFOファイルの形式で、関連するパス名は、ファイルシステム内に存在提供します。長いパスへのアクセスとして、それが通信を介して可能であるようにこのように、プロセスの遺伝的関係を作成FIFOプロセスは、FIFOは、対応しているディスク上に、互いに(プロセス間のパスとFIFOを作成するプロセスにアクセスすることができる)、存在しなくてもノードが、ブロックしない - つまり、単にmknodeにより、名前と適切なアクセス権を持っている()システムコールやはmkfifo()関数が作成します。設立後は、任意のプロセスがそれを開いて、読み取りおよび書き込み、ファイル名ではなく、親と子に限定されないことができ、もちろん、前提は、適切なアクセス権を持っているFIFOのプロセスです。プロセスが使用されなくなった場合は、メモリ内のFIFOのリリースが、ディスクノードが残っていません。

したがって、FIFO無関係なプロセスがデータを交換することができます。これは、ことは注目に値する、厳密には、FIFO(先入れ先出し)FIFOに従って読み、FIFOパイプラインは常に最後にそれらを置くためにデータを書き込むために追加して、最初からデータを返します。彼らはそのようにlseek()と位置決め運転、他の文書として、サポートしていません。

7、匿名パイプと名前付きパイプの違い

2間の最大の違いはあります

有名在任意两个进程间可以通信
无名只能在父子进程间通信

また、黒書き込みのパイプブログ小さなアプリケーションを実装命名。

公開された29元の記事 ウォン称賛65 ビュー10000 +

おすすめ

転載: blog.csdn.net/weixin_46027505/article/details/105151719