Linuxの下のプロセスの通信方式:有名なパイプ(名前付きパイプ)


1.有名なパイプ(名前付きパイプ)の説明
  • ネーミングパイプは、パス名によって識別され、ファイルシステムで表示されます.
  • がパイプを確立した後、2つのプロセスはそれを通常のファイルのように読み書き操作することができる.
  • ネーミングパイプ(FIFO)は、匿名パイプが親縁関係を有するプロセス間でのみ使用できるという制限を突破し、互いに関連しない2つのプロセスを互いに通信させることができる.
  • 匿名パイプと同様に、FIFOも先進的な先出し規則に厳格に従っており、パイプおよびFIFOの読み取りは常に最初からデータを返し、それらの書き込みは末尾にデータを追加し、lseek()などのファイルの位置決め操作をサポートしていない.

  • 名前付きパイプの作成:
  • は、関数mkfifo()を使用して、パイプのパス、名前、および開くモードを指定できます.
  • shellコマンド:mknod pipe_を使用できます.name  p

  • 名前付きパイプの読み書き:
  • ネーミングパイプの作成に成功したら、open()、read()、write()関数を使用できます.
  • 読み取りのために開いたパイプについてopen()でO_を設定できます.RDONLY
  • 書き込みのために開いているパイプについてopen()でO_を設定できます.WRONLY

  • 名前付きパイプと一般ファイルの違い:
  • 通常ファイルの読み書き時にブロック問題が発生しない
  • は、名前付きパイプの読み書きでブロックされる可能性があります.

  • Open()関数では、モードをO_に設定できます.NONBLOCKは非ブロッキング方式で開く.
    (2)名前付きパイプの閉塞と非閉塞開放方式における読み書き問題
    (1)リードプロセスの場合.
  • パイプが閉塞オープンであり、現在のFIFO内にデータがない場合、データ書き込みがあるまでリードプロセスは閉塞される.
  • このパイプが非ブロックで開いている場合、FIFO内にデータがあるかどうかにかかわらず、リードプロセスはすぐにリード操作を実行します.すなわち、FIFO内にデータがない場合、読み出し関数は直ちに−1を返す.

  • (2)書き込みプロセスについて.
  • パイプが閉塞開放されている場合、書き込み操作は、データが書き込み可能になるまで閉塞される.
  • このパイプが非ブロックで開いていて、すべてのデータを書き込むことができない場合、書き込み操作は部分的な書き込みまたは呼び出しに失敗します.

  • mkfifo()関数フォーマット:
    3.使用例
    インスタンスには2つのプログラムが含まれています
  • リードパイプ(fifo_read.c)
  • 配管
  • を作成する
  • リードパイプ
  • 書き込み用パイプ(fifo_write.c)
  • は、main()関数のパラメータによって、ユーザが書き込む必要があるコンテンツ
  • に入力する.
  • パラメータの内容をパイプ
  • に書き込む.

    両方のプログラムは、ブロック型読み書きパイプモードを採用しています.
    /*  fifo_write.c  */
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    
    #define MYFIFO   "/tmp/myfifo"    /*        */
    #define MAX_BUFFER_SIZE   PIPE_BUF   
    /*  PIPE_BUF     limits.h */
    
    int main(int argc, char * argv[]) /*           */
    {
    	    int fd;
    	    char buff[MAX_BUFFER_SIZE];
    	    int nwrite;
    	    
    	    if(argc <= 1)
    	    {
    		printf("Usage: ./fifo_write  string
    "); exit(1); } sscanf(argv[1], "%s", buff); /* FIFO */ fd = open(MYFIFO, O_WRONLY); if (fd == -1) { printf("Open fifo file error
    "); exit(1); } /* */ if ((nwrite = write(fd, buff, MAX_BUFFER_SIZE)) > 0) { printf("Write '%s' to FIFO
    ", buff); } close(fd); exit(0);4 }

    /*  fifo_rear.c  */
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <string.h>
    
    #define MYFIFO   "/tmp/myfifo"    /*        */
    #define MAX_BUFFER_SIZE   PIPE_BUF   
    /*  PIPE_BUF     limits.h */
    
    int main()
    {
    	 char buff[MAX_BUFFER_SIZE];
    	 int  fd;
    	 int  nread;
    	 /*            ,     ,         */
    	 if (access(MYFIFO, F_OK) == -1) 
    	 {      
    		if ((mkfifo(MYFIFO, 0666) < 0) && (errno != EEXIST))
    		{   
    			 printf("Cannot create fifo file
    "); exit(1); } } /* */ fd = open(MYFIFO, O_RDONLY); if (fd == -1) { printf("Open fifo file error
    "); exit(1); } while (1) { memset(buff, 0, sizeof(buff)); if ((nread = read(fd, buff, MAX_BUFFER_SIZE)) > 0) { printf("Read '%s' from FIFO
    ", buff); } } close(fd); exit(0); }

    実行:
  • まず、リードパイププログラムを開始する.リードパイププロセスは、パイプが確立された後、パイプからコンテンツを循環的に読み出し始め、データが読み取り可能でなければ、ライトパイププロセスがパイプにデータを書き込むまでブロックされる.
  • ライトパイププログラムを再起動する:リードプロセスはパイプからユーザーの入力内容を読み出すことができる.

  • スクリーンショットの実行:
    匿名パイプに関する知識、ブログを参照:http://blog.csdn.net/rl529014/article/details/51464363