现在的位置: 首页 > 综合 > 正文

进程间通信——FIFO

2013年09月09日 ⁄ 综合 ⁄ 共 2017字 ⁄ 字号 评论关闭

管道没有名字,只能用于有一个共同祖先进程的各个进程之间。

FIFO指代先进先出,它是一个单向的数据流,每个FIFO有一个路径名与之相关联,从而允许无亲缘关系的进程访问同一个FIFO。FIFO也被称为有名管道。

#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode); //返回:成功为0,出错为-1

创建出一个FIFO之后,它必须或者打开来读,或者打开来写。FIFO是半双工的,不能打开来既读又写。对管道或FIFO的write总是往末尾添加数据,对它们的read总是从开头返回数据。不能对管道或FIFO调用lseek,否则返回ESPIPE。两个进程打开FIFO用于读写有顺序关系:如果当前没有任何进程打开某个FIFO来写,那么打开该FIFO来读的进程将阻塞,如果考虑不当,两进程可能会出现死锁

无亲缘关系的客户/服务器:

//fifo.h

#include	"unpipc.h"

#define	FIFO1	"/tmp/fifo.1"
#define	FIFO2	"/tmp/fifo.2"

//server.c

#include	"fifo.h"

void	server(int, int);

int main(int argc, char **argv)
{
	int		readfd, writefd;

		/* 4create two FIFOs; OK if they already exist */
	if ((mkfifo(FIFO1, FILE_MODE) < 0) && (errno != EEXIST))
		err_sys("can't create %s", FIFO1);
	if ((mkfifo(FIFO2, FILE_MODE) < 0) && (errno != EEXIST)) {
		unlink(FIFO1);
		err_sys("can't create %s", FIFO2);
	}

	readfd = Open(FIFO1, O_RDONLY, 0);
	writefd = Open(FIFO2, O_WRONLY, 0);

	server(readfd, writefd);
	exit(0);
}

void server(int readfd, int writefd)
{
	int		fd;
	ssize_t	n;
	char	buff[MAXLINE+1];

		/* 4read pathname from IPC channel */
	if ( (n = Read(readfd, buff, MAXLINE)) == 0)
		err_quit("end-of-file while reading pathname");
	buff[n] = '\0';		/* null terminate pathname */

	if ( (fd = open(buff, O_RDONLY)) < 0) {
			/* 4error: must tell client */
		snprintf(buff + n, sizeof(buff) - n, ": can't open, %s\n",
				 strerror(errno));
		n = strlen(buff);
		Write(writefd, buff, n);

	} else {
			/* 4open succeeded: copy file to IPC channel */
		while ( (n = Read(fd, buff, MAXLINE)) > 0)
			Write(writefd, buff, n);
		Close(fd);
	}
}

//client.c

#include "fifo.h"

void client(int, int);

int main(int argc, char **argv)
{
	int		readfd, writefd;

	writefd = Open(FIFO1, O_WRONLY, 0);
	readfd = Open(FIFO2, O_RDONLY, 0);

	client(readfd, writefd);

	Close(readfd);
	Close(writefd);

	Unlink(FIFO1);
	Unlink(FIFO2);
	exit(0);
}

void client(int readfd, int writefd)
{
	size_t	len;
	ssize_t	n;
	char	buff[MAXLINE];

		/* 4read pathname */
	Fgets(buff, MAXLINE, stdin);
	len = strlen(buff);		/* fgets() guarantees null byte at end */
	if (buff[len-1] == '\n')
		len--;				/* delete newline from fgets() */

		/* 4write pathname to IPC channel */
	Write(writefd, buff, len);

		/* 4read from IPC, write to standard output */
	while ( (n = Read(readfd, buff, MAXLINE)) > 0)
		Write(STDOUT_FILENO, buff, n);
}

O_NONBLOCK标志对管道和FIFO的影响:

抱歉!评论已关闭.