Linuxプロセス間通信(IPC)の二——命名配管(FIFO)



1配管名(FIFO)
      前の文章の「Linuxプロセス間通信(IPC)」でパイプラインを紹介しましたが、パイプライン応用の大きな欠陥は名前がないので、親縁プロセス間の通信にしか使えません。その後、パイプをベースにした命名パイプ(named pipe,FIFO)の概念が提案され、この制限は克服された。FIFOはパイプラインとは異なり、FIFOのファイル形式でファイルシステムに存在する経路名と関連付けられている。このように、FIFOの作成プロセスに親縁関係のプロセスが存在しなくても、この経路にアクセスできる限り、互いにFIFOを介して通信することができる(この経路にアクセスできるプロセスとFIFOの作成プロセスとの間)ので、FIFOに関係のないプロセスを通じてデータを交換することができる。注意すべきことは、FIFOは先進先の先出に厳格に従い、パイプ及びFIFOに対する読み取りはいつも最初からデータに戻り、それらの書き込みは最後までデータを追加する。これらはlseek()などのファイルポジショニング動作をサポートしていません。
2命名配管の作成
#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode); 
     この関数はFIFOを作成し、FIFOはファイルシステムでファイルとして表現され、ファイルのパスはパラメータpathnameによって指定されます。二つ目のパラメータmodeとシステム呼び出しopen関数のmodeは同じです。パス下のファイルが既に存在すると、mkfifoは-1に戻り、erronoはEEXISTに戻ります。
3配管名操作
     FIFOはファイルシステムで一つのファイルとして表現されています。ほとんどのシステムファイルの呼び出しはFIFOの上で使用できます。例えば、read、open、write、close、unlink、statなどの関数です。ただし、seekなどの関数はFIFOに対して呼び出すことができません。
    openを呼び出してFIFOを開くことができます。以下の点に注意してください。
1、FIFOをブロック(OuNONBBLOCKを指定していない)方式でのみ開くと、他のプロセスが書き込みで開くまでブロックされます。
2、同様に、ブロック(OuNONBBLOCKを指定していない)方式でFIFOを開くだけと書くと、他のプロセスが読み込むようにFIFOを開くまでブロックされます。
3、FIFOを開いているだけが閉塞していない方式(OuNONBBLOCKを指定)である場合、直ちに-1に戻ります。そのerrnoはENXIOです。
    前文で
を選択します
Linuxプロセス間通信(IPC)の一つである配管
」に言及しました。配管に書き込むデータ量がPIPE_に等しい場合BUF、システムはwriteが原子の操作であることを保証して、複数のプロセスは同時にパイプを書きます。書き込みデータ量がPIPE_より大きい場合BUFの場合、システムはwriteが原子操作であることを保証しないで、複数のプロセスが同時に配管を書きます。この規則はネーミングパイプで引き続き適用される。
4アプリケーションの例     本例はclient-serverモードであり、サーバー側は有名なfifoファイル(本例では「/tmp/server」)を作成し、ファイルを読み込む。クライアントは、このfifoファイルを開き、その要求をFIFOファイルに書き込む。サーバー側でこのコマンドを読み込み、実行します。     サーバ側のコードは以下の通りです。  #include艦include鞥includecmd{pidtchild upld;char cmd[100];;int main(void){int fd;structfifouct fifoucmd cmd;int err;int n;if((err=mkfifo("/tmpp/server ver]、<07777){if(errno!=EEXIST){perror(“mkfido fail:”);exfidofail(("))))、(((((")))))))"""""""""""""""""""""""""""""""((((((((((((((((((((((")))))))))))))))))));exit(-1);}while(1){if(((((n=read(fd、&cmd、sizeof(cmd)))<0)}{perror(“read fail:”);exit(-1);}if(n>0){printf("command from%d:%s/n",cmd.child_bid,cmd.cmd);sleep(1);}  このコードをserverにコンパイルします。     クライアントコードは以下の通りです。cmd{pidtu pid;char cmd[100];;main(int argc,char*argv[]{int fd;strut fifouucmd cmd;if((fd=open)((("/tmp/server]、{0){perror("open fail:");exit(-1);cddd. pigele="((““")、(((")]]]]]]]]、((((((((((("))))))))))))))))""""""""""""""""""""""""""")""""""""""""""""""""""""""""");cmd.cmd[streen(cmd.cmd)-1]=0;if(write(fd,&cmd,sized)<0){perror];exit(-1);}  クライアントコードをclientにコンパイルします。     テスト時に複数のclientを起動できます。clientの発生命令はサーバー側で実行されます。5まとめ     パイプラインと比べて、FIFOの最大の特徴はファイルシステムにfifoファイルが存在し、プロセス間通信が可能になることです。