您的位置:首页 > 理论基础 > 计算机网络

进程间通信——FIFO

2013-05-06 16:01 330 查看
管道没有名字,只能用于有一个共同祖先进程的各个进程之间。

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
= '\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的影响:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息