FIFO

Pipes have no names, and their biggest disadvantage is that they can be used  only between processes that have a parent process in common. Two unrelated processes can-

not create a pipe between them and use it for IPC

FIFO stands for first in, first out, and a Unix FIFO is similar to a pipe. It is a one-way (half-duplex) flow of data. But unlike pipes, a FIFO has a pathname associated with it, allowing unrelated processes to access a single FIFO.

FIFO是有名管道,有一个路径与之关联,允许无亲缘关系的进程通信,单向。

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo (const char *pathname, mode-t mode)

Returns: 0 if OK, -1 on error

创建一个新的fifo或者返回错误,如果返回错误使用open或fopen打开,FIFO是半双工,不能同时读和写

#include	"unpipc.h"

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

void	client(int, int), server(int, int);

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

		/* 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);
	}

	if ( (childpid = Fork()) == 0) {		/* child */
		readfd = Open(FIFO1, O_RDONLY, 0);
		writefd = Open(FIFO2, O_WRONLY, 0);

		server(readfd, writefd);
		exit(0);
	}
		/* 4parent */
	writefd = Open(FIFO1, O_WRONLY, 0);
	readfd = Open(FIFO2, O_RDONLY, 0);

	client(readfd, writefd);

	Waitpid(childpid, NULL, 0);		/* wait for child to terminate */

	Close(readfd);
	Close(writefd);

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

无亲缘关系的客户与服务器

server_main.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);
}

fifo.h

#include	"unpipc.h"

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

client_main.c

#include	"unpipc.h"

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);
}

单个服务器,多个客户

单个服务器,多个客户:服务器以一个众所周知的路径名创建一个FIFO,从这个FIFO读入客户的请求。每个客户在启动时创建自己的FIFO,所用的路径名包含有自己的进程id。每个客户把自己的请求写入服务器的众所周知的FIFO中,请求中包含客户的进程id以及一个路径名。具有该路径名的文件就是客户希望服务器打开并发回的文件。

FIFO,布布扣,bubuko.com

时间: 2024-08-08 03:22:47

FIFO的相关文章

操作系统 页面置换算法LRU和FIFO

LRU(Least Recently Used)最少使用页面置换算法,顾名思义,就是替换掉最少使用的页面. FIFO(first in first out,先进先出)页面置换算法,这是的最早出现的置换算法.该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最长的页面给予淘汰. FIFO置换算法有这样一个奇怪现象:内存空间块数越多,缺页中断率可能相反的越高(缺页中断次数越高). LFU(Least Frequently Used)最近最少使用算法,它是基于“如果一个数据在最近一段时间内使用次

命名管道(FIFO)

一.命名管道:两个不相关的进程通过一个路径名关联,即,只要可以访问该路径,就能实现进程间的通信(先入先出). 二.创建函数原型:int mkfifo(const char*path, mode_t mode);    //成功返回0,失败返回-1 三.代码实现: //write端 #include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> #include&l

进程间通信IPC-命名管道FIFO

FIFO又被称为命名管道,未命名的管道只能在两个相关的进程之间使用,而这两个相关的进程还要有一个共同创建了它们的祖先进程,但是FIFO,不相关的进程之间也能交换数据. FIFO是一种文件类型.通过stat结构的st_mode成员的编码可以知道文件是否是FIFO类型,在linux下查看自己创建的FIFO文件: 创建FIFO类似于创建文件,也存在于文件系统之中.定义如下: #include <sys/stat.h> int mkfifo(const char* path, mode_t mode)

第4章 管道和FIFO

4.1 管道 管道是由pipe函数创建的,提供一个单向数据流. 头文件 #include <unistd.h> 函数原型 int pipe(int fd[2]); 返回值 成功则为0,出错则为-1 函数功能 该函数返回两个文件描述符:fd[0]和fd[1].fd[0]用来读操作,fd[1]用来写操作 说明 管道只能用于有亲缘关系进程间通讯.要实现非亲缘关系进程间通讯用有名管道FIFO 4.2 管道实现半双工通讯 实现的步骤: (1)创建管道(fd[0]和fd[1]) (2)fork (3)父进

一个好用的fifo

改造的Nordic库中的 E:\nRF52_SDK_0.9.2_dbc28c9\components\libraries\fifo sensor_fifo.c #include "sensor_fifo.h" static __INLINE uint32_t fifo_length(sensor_t * p_fifo) { uint32_t tmp = p_fifo->read_pos; return p_fifo->write_pos - tmp; } #define F

进程间通信之管道(pipe、fifo)

我们先来说说进程间通信(IPC)的一般目的,大概有数据传输.共享数据.通知事件.资源共享和进程控制等.但是我们知道,对于每一个进程来说这个进程看到属于它的一块内存资源,这块资源是它所独占的,所以进程之间的通信就会比较麻烦,原理就是需要让不同的进程间能够看到一份公共的资源.所以交换数据必须通过内核,在内核中开辟?块缓冲区,进程1把数据从?户空间 拷到内核缓冲区,进程2再从内核缓冲区把数据读?,内核提供的这种机制称为进程间通信.一般我们采用的进程间通信方式有 管道(pipe)和有名管道(FIFO)

练习--LINUX进程间通信之有名管理FIFO

从FIFO中读取数据: 约定:如果一个进程为了从FIFO中读取数据而阻塞打开FIFO,那么称该进程内的读操作为设置了阻塞标志的读操作. 如果有进程写打开FIFO,且当前FIFO内没有数据,则对于设置了阻塞标志的读操作来说,将一直阻塞.对于没有设置阻塞标志读操作来说则返回-1,当前errno值为EAGAIN,提醒以后再试. 对于设置了阻塞标志的读操作说,造成阻塞的原因有两种:当前FIFO内有数据,但有其它进程在读这些数据:另外就是FIFO内没有数据.解阻塞的原因则是FIFO中有新的数据写入,不论信

O_NONBLOCK模式下写fifo的注意事项

后台网络通信框架一般采用fifo来作为事件通知的机制:创建一个fifo,然后以非阻塞读和非阻塞写的方式打开fifo,然后把fd加到epoll里面,作为通知网络事件的fd. 在这里有个隐晦的问题容易被忽视.fifo在以非阻塞模式打开时,必须先打开读,然后打开写.不然会报错No such device or address.即如下代码所示是正确的 #define FIFO_FILE "/tmp/fifo.xxx" #define FIFO_MODE FILE_MODE S_IRUSR |

Linux IPC实践(3) --具名FIFO

FIFO具名/命名管道 (匿名)管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信. 如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道;命名管道是一种特殊类型的文件. 创建一个命名管道 1)命名管道可以从命令行上创建: $ mkfifo <filename> 2)命名管道在程序里创建: #include <sys/types.h> #include <sys/stat.h> int mkfifo(const

FIFO管道探索历程

刚开始代码的实现如下: void CreateFIFO(){    if((mkfifo(FIFOPATH,O_CREAT|O_EXCL|O_RDWR)<0)&&(errno!=EEXIST))    {        printf(strerror(errno));    }   } int OpenFIFO(){    fd=open(FIFOPATH,O_RDWR|O_NONBLOCK);    return fd;} 觉得非常的不优雅,毕竟需要调用两个函数,而且写函数又有一个