进程间通信——FIFO

来源:互联网 发布:铃声放大软件 编辑:程序博客网 时间:2024/06/06 19:44

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

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"#defineFIFO1"/tmp/fifo.1"#defineFIFO2"/tmp/fifo.2"

//server.c#include"fifo.h"voidserver(int, int);int main(int argc, char **argv){intreadfd, 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){intfd;ssize_tn;charbuff[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){intreadfd, 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_tlen;ssize_tn;charbuff[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的影响:


原创粉丝点击