日期:2014-05-16  浏览次数:20644 次

Linux学习记录--有名管道通信

有名管道通信

 

什么是有名管道

 

匿名管道应用的一个重大限制是它没有名字,因此,只能用于具有亲缘关系的进程间通信,在有名管道(named pipeFIFO)提出后,该限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信

 

有名管道创建

 

int mkfifo(const char * pathname, mode_t mode)

 和普通文件创建一样pathname为文件名称,mode为权限

 

有名管道通信规则

 

管道关闭规则

 

intclose (int __fd);

 

1.当最后一个读进程管道关闭时,写进程无论是阻塞还是非阻塞,都会将管道写满(如果能写满)并退出

2.当最后一个写进程管道关闭时,向管道写入一个结束标识,当读进程从管道读到这个结束标识时,如果是阻塞读进程将结束阻塞返回读入数据个数为0.(对于未阻塞读进程如果管道内没有数据则返回-1,如果读到结束标识则返回读入数据个数为0

 

规则分析1

 

写进程:

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<fcntl.h>
#include<limits.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>

#define FIFO_NAME "/tmp/my_fifo"
#define BUF_SIZE 80000
intmain(int argc,char *argv[])
{
	unlink(FIFO_NAME);
int pipe_fd;
int res;
char buf[BUF_SIZE];
memset(buf,3,BUF_SIZE);
if(access(FIFO_NAME,F_OK)==-1)
    {
        res=mkfifo(FIFO_NAME,0766);
if(res!=0)
        {
fprintf(stderr,"不能创建管道文件 %s\n",FIFO_NAME);
exit(1);
        }
    }

printf("进程PID %d 打开管道 O_WRONLY\n",getpid());
    pipe_fd=open(FIFO_NAME,O_WRONLY);

if(pipe_fd!=-1)
    {
        res=write(pipe_fd,buf,sizeof(buf));
printf("写入数据的大小是%d \n",res);
close(pipe_fd);
sleep(1000);
    }
else
exit(1);
exit(1);
}

读进程

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<fcntl.h>
#include<limits.h>
#include<sys/types.h>
#include<sys/stat.h>

#define FIFO_NAME "/tmp/my_fifo"
#define BUF_SIZE 20

intmain(int argc, char *argv[]) {
	char buf[BUF_SIZE];
	memset(buf, 0, BUF_SIZE);
	int pipe_fd;
	int res;
	int bytes_read = 0;

	printf("进程PID %d 打开管道 O_RDONLY\n", getpid());
	pipe_fd = open(FIFO_NAME, O_RDONLY);

	if (pipe_fd != -1) {
		bytes_read = read(pipe_fd, buf, sizeof(buf));
		printf("读入数据的大小是%d \n", bytes_read);
		sleep(10);
		close(pipe_fd);
	} else
		exit(1);
	exit(1);
}

控制台信息