FIFO

本文深入探讨了FIFO(命名管道)与传统管道在进程间通信中的作用与区别,详细介绍了FIFO的设计目标、工作原理及应用设计。通过具体代码示例,展示了如何使用FIFO在两个不相关进程间建立通信,包括客户进程与服务进程之间的消息传递。

1. FIFO VS 管道

1.1 FIFO简介

设计目标:

  1. 进程之间通过字节流的方式进行通信!
  2. 管道是以半双工方式工作的

设计限制:
       无须亲缘关系

FIFO说明:
       FIFO又叫做命名管道,它和进程间通信的PIPE模型大体一致,仅有的区别如下:

  1. 一个FIFO是文件系统上的磁盘文件,实现进程间通信不需要进程具有亲缘关系
  2. 一个FIFO文件需要创建(mkfifo),打开(open),这是PIPE没有的
  3. 命名管道在打开(open)时可能会发生阻塞(没有为写打开管道的进程时发生)

在这里插入图片描述

1.2 过程演示

进程A以只读方式打开命名管道fifoname,会一直阻塞
稍后,启动进程B;进程B以写方式打开命名管道fifoname,进程A此时解除open阻塞
接着,进程B向进程A递送信息
在这里插入图片描述
进程A代码:打印进程B递送来的消息,直到进程B关闭写端

#include <iostream>
using namespace std;

extern "C" 
{ 	
   /*
   POSIX.1-2001, POSIX.1-2008
   int mkfifo(const char *pathname, mode_t mode);
   RETURN VALUE
       On  success mkfifo() return 0.  In the case of an error, -1 is returned (in which case, errno is set appro‐
       priately).
   */
   #include <sys/types.h>
   #include <sys/stat.h>

   #include <unistd.h>
       #include <fcntl.h>
   #include <stdio.h>

}
char const *fifo_name = "/home/jianleya/fifo/fifo_example";
int main()
{
   
   int res = mkfifo(fifo_name,0666);
   
   cout << "-----------------start open for read" << endl;
   int fd = open(fifo_name,O_RDONLY);
   if(-1 == fd)
   {
   	cout << "open fifo for read only failed" << endl;
   	perror("open");
   	return -1;
   }
   
   while(1)
   {
   	sleep(1);
   	char read_buff[256];
   	size_t size = read(fd,read_buff,256);

   	if(size == -1)
   	{
   		cout << "read failed" << endl;
   	}
   	else if(0 == size)
   	{
   		cout << "reached the end of file" << endl;
   		return 0;
   	}
   	else
   	{
   		
   		int cnt = 0;
   		while(cnt < size)
   		{
   			cout << read_buff[cnt++];
   		}

   	}
   }

   return 0;
}

进程B:向进程A递送消息

#include <iostream>
using namespace std;

extern "C" 
{ 	
	/*
	POSIX.1-2001, POSIX.1-2008
	int mkfifo(const char *pathname, mode_t mode);
	RETURN VALUE
        On  success mkfifo() return 0.  In the case of an error, -1 is returned (in which case, errno is set appro‐
        priately).
	*/
	#include <sys/types.h>
	#include <sys/stat.h>

	#include <unistd.h>
        #include <fcntl.h>
	#include <stdio.h>
	#include <string.h>

}
char const *fifo_name = "/home/jianleya/fifo/fifo_example";
int main()
{
	
	cout << "-----------------start open for write" << endl;
	int fd = open(fifo_name,O_WRONLY);
	if(-1 == fd)
	{
		cout << "open fifo for write only failed" << endl;
		perror("open");
		return -1;
	}
	
	char const*msghead = "A message from a friend:\n";
	char const*msgtext = "Hello,Bob: \nIt's been a long time since , I've missed you!\n";
	size_t size = write(fd,msghead,strlen(msghead));

	size = write(fd,msgtext,strlen(msgtext));
	

	close(fd);
	return 0;
}

输出结果
在这里插入图片描述

2. FIFO应用设计

2.1 客户进程 与 服务进程

客户进程通过唯一的FIFO向服务器递送消息(注意:一次递送消息字节数 < PIPE_BUFF)
服务器向客户端递送相应,每一个客户端需要一个单独的FIFO
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值