1. 程式人生 > >Linux程序間通訊————無名/有名管道

Linux程序間通訊————無名/有名管道

管道簡介:

管道是Linux中程序間通訊的一種方式,它把一個程序的輸出直接連線另一個管道的輸入。Linux的管道包括兩種:無名管道和有名管道。

1.無名管道

特點:

  1. 只能用於具有親緣關係的程序間通訊(及父子或者兄弟程序)。
  2. 是一種單工的通訊模式,具有固定的讀端和寫端。
  3. 管道也可以看成一種特殊的檔案進行操作,對於它的讀寫也可以使用普通的read(),write()等函式。但是它不屬於任何檔案系統,並且只存在於核心中。
  4. 資料的讀出和寫入:一個程序向管道中寫的內容被管道另一端的程序讀出。寫入的內容每次都新增在管道緩衝區的末尾,並且每次都是從緩衝區的頭部讀出資料。

注意:

  1. 只有在管道的讀端存在時,向管道寫入資料才有意義,否則,向管道寫資料的程序將收到核心傳來的SIGPIPE訊號(通常Broken Pipe錯誤)。
  2. 向管道寫入資料時,Linux將不具有原子性,管道緩衝區只要有空間,寫程序就試圖向管道寫資料。如果管道緩衝區已滿,那麼寫操作將會一直阻塞。
  3. 父程序在執行時,它們的先後次序並不能保證。為了確保父程序已經關閉了相應的檔案描述符,可在兩個程序中呼叫sleep()函式。

管道建立函式:

pipe();

所需標頭檔案: #include<unistd.h>

函式原型: int pipe(int fd[]);

引數:fd:大小為2的整形陣列,用於存放管道的檔案描述符。

返回值:成功:0         錯誤:-1;

例項:

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

int main(int arg,char *argv[])
{
	int fdpi[2]={0};//無名管道的套接的描符存放地址
	char buf[1024];
	if(pipe(fdpi)==-1)
	{
		perror("create pipe is error\n");
		return 0;
	}
	pid_t pid=fork();
	if(pid==-1)
	{
		perror("create fork is error\n");
		return 0;
	}
	else if(pid==0)
	{
		while(1)
		{
        	close(fdpi[0]);//關閉讀埠
			bzero(buf,sizeof(buf));//清空快取區
			gets(buf);
			 if(write(fdpi[1],buf,sizeof(buf))==-1)
			{
				perror("write in fdpi[1] is error\n");
				exit(0);
			}
			if(strcmp("EOF",buf)==0)
			{
				break;
			}
		}
		printf("chid:%d  is quit\n",getpid());	
	}
	else 
	{
		while(1)
		{
		    close(fdpi[1]);//關閉寫埠
			bzero(buf,sizeof(buf));
			if(read(fdpi[0],buf,sizeof(buf))<0)
			{
				perror("read is error\n");
				exit(0);
			}
			if(strcmp("EOF",buf)==0)
			{
				break;
			}
			else
			{
			printf("child message is %s\n",buf);
			}
		}
	    close(fdpi[0]);
	    close(fdpi[1]);
		int cpid=wait(NULL);
		printf("my child: %d is quit\n",cpid);
	}
	return 0;
}