C言語プロセス間通信

5400 ワード

プロセス間通信:1:リソース共有---2:データ伝送---送信受付情報3:通知イベント---信号4:プロセス制御---制御プロセス状態変換比較的古い:無名パイプ(PIPE)有名パイプ(FIFO,named pipe)信号(signal)SYSTEM V IPC信号量(Sem)共有メモリ(shm)メッセージキュー(Msg)BSDソケット(Socket)---ネットワークプログラミング
無名パイプ(PIPE)
int fd[2];0を読んで1を書く--read fd[0],write[1];Open(なし)--->pipe作成して開く機能read/write/close無名パイプ親縁関係のあるプロセスでのみ使用でき、プロセスが終了しても消える(限界)必ずpipe申請パイプを先に行ってforkサブプロセス1:無名パイプにサイズ制限がある(4096 B)空席があれば、中にデータを书くことができます.---データの原子性が満たされた后、データが読み出されてから书き続けるしかありません.n使用4:writeがデータを入力するには、すべてのプロセスにfd[0]が閉じられていない必要があります.fd[0]がオフの場合、writeの場合、カーネルはSIGPIPEの信号を送信します.SIGPIPEに対するプロセスのデフォルト操作はプロセスインスタンスを終了します.
#include 
#include 
#include 
#include 

void sig_isr(int sig)
{
	printf("catch a SIGPIPE %d 
", sig); //exit(0); } int main(void) { pid_t pid; int fd[2]; char buf[100]; if(pipe(fd) == -1) { perror("pipe error"); exit(1); } printf("fd[0] = %d , fd[1]= %d
", fd[0], fd[1]); // 3,4。 1,2 if((pid = fork())< 0) { perror("fork error"); exit(1); } else if(pid == 0)// read { // 0 1 -- read fd[0] , write [1]; close(fd[1]);// printf("ready to read...
"); read(fd[0], buf, 100); // printf("%s
", buf); /* read write, f[0] write SIGPIPE, SIGPIPE */ close(fd[0]); _exit(0); } else // write { signal(SIGPIPE , sig_isr); sleep(1);// for check read's hangup close(fd[0]);// , , 。 printf("start write
"); write(fd[1], "hello world
", 100); printf("end write
"); close(fd[1]); wait(NULL); printf("exit
"); exit(0); } }
有名なパイプ(FIFO,named pipe)
FIFOには具体的なファイルがあります
mkfifo FIFO-m 0666---shell命令mkfifo(「path」,0666)--関数を使用して作成、mode&~umask
操作:open/close/read/writeは、任意の2つのプロセスでopen(「path」)O_を通信できます.RDONLY O_WRONLYO_RDWR(FIFOはRDWRを使用しない)|O_APPEND(wrと併用、追加)|O_TRUNC(wrと併用、上書き、直接クリアしてから書き込み、FIFOまたはデバイスファイルに対して無効)|O_CREAT|O_EXCL(既に存在する場合は失敗を返す;FIFOはopenの中のCREATで作成できない)|O_NONBLOCK読み書き方式|書き方|作成してチェック|open(fifo,O_WRONLY|O_NONBLOCK)をブロックせずに読み書き方式で開くことができるかどうかを見て、すぐに失敗を返すことはできません.例えば、プロセスがなくて読み取り専用で開く場合、1:open(fifo,O_RDONLY);   open(fifo, O_WRONLY);どちらを先に実行しても、別のプロセスが対応する接続を開くのを待ってからopenがreaderを終了するopenはwriterのopenが実行されてからopenが終了し、逆も2:open(fifo,O_RDONLY|O_NONBLOCK);writerがファイルを開くのを待たない3:open(fifo,O_WRONLY|O_NONBLOCK):readerがこのパイプファイルを開かなければ、直接エラーを報告し、プロセスを終了してperrorで情報をつかむ.No such device or address注意:1:パイプにサイズ制限があります(4096 B)データを書き込む前に、パイプの大きさが十分かどうかを判断し、足りなければ書き込まない--データの原子性が満たされていることを保証した後、データが読み出されるまで待つしかない.によるとreaderが完全にオフになっている場合、writeのときにカーネルからSIGPIPEの信号が送信されます.プロセスのSIGPIPEに対するデフォルトの操作はプロセスを終了します.4:writerが非ブロックに設定されている場合は、readerを先に実行しなければなりません.そうしないと通信できません.Open(fifo,O_WRONLY|O_NONBLOCK):unlink()を参照して、使用する必要がなくなったファイルを削除し、スパムファイルを回避します.mkfifoの作成に対応します.
例:
fifoReader.c
#include 
#include 
#include 
#include 
#include 
#include 

#define FIFO "/root/c/process/ififo"

int main(void)
{
	int fd;
	char buf[128];

	if(mkfifo(FIFO, 0666))//      
	{
		 perror("Mkfifo error");
	}
	printf("open for reading... 
"); // fd=open(FIFO,O_RDONLY);// fd=open(FIFO,O_RDONLY|O_NONBLOCK);// /* 1:open(fifo, O_RDONLY); open(fifo, O_WRONLY); , open reader open writer open open , 2:open(fifo, O_RDONLY|O_NONBLOCK ); writer 3:open(fifo , O_WRONLY|O_NONBLOCK): reader , , perror , No such device or address reader */ printf("opened ...
"); if(fd<0) { perror("Failed to open fifo:"); return -1; } while(1) { int count; count=read(fd,buf,127); // io。read() if(count>0) { buf[count]=0;// , ='\0'; printf("fifoReader receive a string:%s
",buf); } if(strncmp(buf,"exit",4)==0) { break; } } close(fd); return 0; }

fifoWriter.c
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define FIFO "/root/c/process/ififo"
int main(void)
{
	int fd;
	char buf[128];

	if(mkfifo(FIFO, 0666))
	{
		perror("Mkfifo error");
	}
	printf("open for writing ... 
"); // fd=open(FIFO,O_WRONLY);// fd=open(FIFO,O_WRONLY|O_NONBLOCK);// , , open printf("opened...
"); if(fd<0) { perror("Failed to open fifo:"); return -1; } while(1) { fgets(buf,128,stdin);// write(fd,buf,strlen(buf));// if(strncmp(buf,"exit",4)==0) { break; } } close(fd); unlink(FIFO); return 0; }

違い:
無名パイプ1:親縁関係プロセス中2:具体的なファイルが1つもない3:writeを呼び出すときにfd[0]があることを保証しなければならないclosed 4:pipeがforkの前に(パイプを申請して開く)5:データを書き込むことを保証しない原子性有名パイプ1:任意の2:具体的なファイル3:writeを呼び出すときにリードを保証しなければならない(RDONLYの方式)はclosed 4:mkfifo(申請)open(path,O_RDONLY)がブロックされていません.readはブロックされています.データが読めるのを待ってopen(path,O_RDONLY|O_NONBLOCK)がブロックされていません.readもブロックされていません.データがないのは0 5です.データが書き込まれている原子性を保証します.6:有名なパイプファイルはwindowに存在しません.