Linuxプロセス間通信(二)パイプ

13177 ワード

Linuxプロセス間通信-パイプ
プロセスは独立したリソース割り当て単位であり、異なるプロセス間のリソースは互いに独立しており、関連付けられておらず、あるプロセスで別のプロセスのリソースに直接アクセスすることはできません.しかし,プロセスは孤立ではなく,異なるプロセス間では情報の交換や状態の伝達が必要であるため,プロセス間のデータ伝達,同期,非同期のメカニズムが必要である.
このブログにはパイプが記録されています.
パイプpipe
パイプはプロセス間通信の主な手段の一つである.1つのパイプは、実際にはメモリにのみ存在するファイルであり、このファイルの操作は、パイプの両端を表す2つの開いたファイルで行います.パイプは特殊なファイルで、あるファイルシステムに属していないが、独立したファイルシステムであり、独自のデータ構造を持っている.パイプの適用範囲に応じて、無名パイプと名前付きパイプに分けます.
パイプ分類
●無名ダクト
主に親プロセスと子プロセス、または2つの兄弟プロセスの間で使用されます.linuxシステムでは、システム呼び出しによって一方向の通信パイプを構築することができ、この関係は親プロセスによってのみ確立できます.従って、各パイプは一方向であり、双方向通信が必要な場合には2つのパイプを構築する必要がある.パイプの両端のプロセスは、パイプをファイルと見なします.1つのプロセスはパイプに内容を書き、もう1つはパイプから読み取ります.この伝送は「先入先出」(FIFO)の規則に従う.
●名前付きパイプ
名前付きパイプは、無名パイプが近親プロセス間の通信にしか使用できない欠陥を解決するために設計されています.ネーミングパイプは、メモリにのみ存在するのではなく、実際のディスクメディアまたはファイルシステムに独自の名前のファイルを作成し、任意のプロセスがファイル名またはパス名でファイルにいつでも連絡を取ることができます.ネーミングパイプを実現するために、FIFOファイルという新しいファイルタイプが導入されました(先進的な先出しの原則に従います).名前付きパイプを実装することは、実際にはFIFOファイルを実装することです.名前付きパイプが作成されると、読み取り、書き込み、閉じる操作は通常のパイプとまったく同じです.FIFOファイルのinodeノードはディスク上にありますが、1つのノードだけで、ファイルのデータはメモリバッファページに存在し、通常のパイプと同じです.
パイプの読み書き
パイプに書き込まれたデータは到着順に並べられます.パイプがいっぱいになると、パイプのデータが読み出されるまでパイプの書き込みがブロックされます.書き込み操作では、write呼び出し書き込みのデータ量がパイプ容量より小さい場合、書き込みは一度に完了しなければならない.すなわち、パイプの残りの容量が足りない場合、writeはパイプの残りの容量が一度に書き終わるまでブロックされる.write呼び出し書き込みのデータ量がパイプ容量より大きい場合、書き込み操作は複数回に分けて完了します.fcntlでパイプ書き込みポートを非ブロック方式に設定すると、パイプがいっぱいになっても書き込みがブロックされず、書き込みに対して0が返されます.
読み出し操作は、データが到着した順にデータを読み出す.読み込まれたデータはパイプ内には存在しません.これは、パイプ内でデータが再利用できないことを意味します.パイプが空で、パイプのライトポートが開いている場合、データが書き込まれるまでリード操作がブロックされます.1回のread呼び出しで、パイプ内のデータ量がreadで指定した数に満たない場合は、実際の数で読み取り、readに対して実際の数の値を返します.リードポートがfcntlを使用して非ブロック方式を設定している場合、read呼び出しはパイプが空の場合に0を返します.
パイプのリードポートがオフの場合、パイプ上の書き込み操作呼び出しを発行するプロセスはSIGPIPE信号を受信する.ライトポートを閉じることは、読み取りポートにファイルの終端を与える唯一の方法です.ライトポートがオフの場合、パイプ上のread呼び出しは0を返します.
無名パイプ
親プロセスと子プロセス、または兄弟プロセスの間で使用します.
関数の説明
/*    */



#include <unistd.h>



/*      */

int pipe(int filedes[2]);



/*

filedes[0]            

filedes[1]        



   :     -1,    -1,    errno 



    :

EMFILE              

ENFILE            

EFAULT   filedes       

*/



/*      */

fcntl(filedes[0], F_SETFL, O_NONBLOCK);

fcntl(filedes[1], F_SETFL, O_NONBLOCK);



/*    */

read(fd, buf, sizeof(buf));

write(fd, buf, sizeof(buf));

≪インスタンス|Instance|emdw≫
#include <unistd.h>

#include <stdio.h>



int main()

{

    int   p[2];

    char  buf[20];

    char  buf0[20];

    pid_t pid;



    strcpy(buf,"Hello World!");



    pipe(p);



    if((pid = fork()) > 0){

        printf("This is father process.

"); write(p[1], buf, strlen(buf)); close(p[1]); close(p[2]); } else{ printf("This is child process.
"); read(p[0], buf0, sizeof(buf0)); printf("%s
", buf0); close(p[0]); close(p[1]); } return 0; }

名前付きパイプ
近親プロセス間の通信に使用できます.
関数の説明
/*      */



#include <sys/types.h>

#include <sys/stat.h>



/*      */

int mkfifo(const  char  *  pathname, mode_t mode);

/*

pathname   ,       

mode            open  Mode

*/



/*      */

int open(const char *pathname,int oflag,... /* mode_t mode */);

/*

mode   :O_RDONLY | O_WRONLY | O_NONBLOC

*/



/*    */

int read(int fd, void *buf, int nbyte)

int write(int fd, void *buf, int nbyte)



/*    */

close(int handle)

≪インスタンス|Instance|emdw≫
/* fifo_write.c */

#include <sys/types.h>

#include <sys/stat.h>

#include <string.h>

#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>



int main()

{

    const char* pathname = "m_fifo";

    int pipe_fd = -1;

    int bytes;

    char buf[20];



    strcpy(buf, "hello world!");



    mkfifo(pathname, 0777);



    pipe_fd = open(pathname, O_WRONLY);



    printf("Process %d result %d
", getpid(), pipe_fd); write(pipe_fd, buf, strlen(buf)); printf("Process %d finished!
", getpid()); return 0; }
#include <unistd.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>



int main()

{

    const char* pathname = "m_fifo";

    char buf[20];

    int pipe_fd;

    

    pipe_fd = open(pathname, O_RDONLY);



    printf("Process %d result %d
", getpid(), pipe_fd); read(pipe_fd, buf, sizeof(buf)); close(pipe_fd); printf("Process %d finished,
read content: %s
", getpid(), buf); return 0; }

リファレンス
http://blog.csdn.net/myarrow/article/details/9037135
http://blog.sina.com.cn/s/blog_4e9440910100yihb.html
http://blog.sina.com.cn/s/blog_67b7d7e401018dvz.html
http://blog.csdn.net/guxch/article/details/6828452
本作品は
知識共有署名-非商業的使用-同じ方法で共有3.0ローカライズされていないバージョンライセンス契約が許可する.転載を歓迎します.出典を明記してください.
転載先:
coco点
http://www.cnblogs.com/coder2012