Linux进程间通信②:有名管道FIFO

常规的匿名管道通过pipe创建一片内存缓冲区,并对外提供两个文件描述符,用于只读或者只写操作。但其使用范围很小,只能用于父、子进程间的通信。因此Linux还提供有名管道的支持。

管道的本质是一片可以读写的缓冲区域,Linux将其描述为文件(UNIX思想:一切IO皆是文件) 对于有名管道,其主要特点是:

  • 存在于文件系统中,包含文件名,管道文件被组织成树状结构
  • 两个进程之间无需有联系,可以通过管道进行通信
  • 对有名管道的操作和文件操作类似,支持读,写

 

【有名管道的创建】

mkfifo(const char* filename,mode)   //创建指定名字的管道文件  并指明mode
int main()
{
    if(mkfifo("./fifo_test",0777)<0)
    {
        cout<<"create fifo error"<

执行结果:

Linux进程间通信②:有名管道FIFO_第1张图片

可以看到,通过mkfifo成功创建了fifo_test的管道文件,但其与磁盘上的普通文件不同,只是对缓冲区的一个抽象描述。

 

基于这个有名管道,fifo_test  可以通过其它进程来实现读写操作。

【写端】

首先通过access判断管道文件是否存在,如果不在,那么mkfifo创建一个管道文件。

然后,不断的接受stdin输入,并通过write写入到管道文件

当输入的字符为'q'时,结束程序

#include "stdio.h"
#include "stdlib.h"
#include
#include 
#include 
#include "sys/types.h"
#include "fcntl.h"
using  namespace std;
int main(int argc, char *argv[])
{
    int i, ret, fd;
    char p_flag = 0;

    /* 创建有名管道 */
    if (access("./myfifo", 0) < 0) {   //先判断有名管道文件是否存在,不存在需要先创建
        ret = mkfifo("./myfifo", 0777);  //权限
        if (ret < 0) {
           cout<<"create fifo error"<>c)
   {
	    write(fd,&c,sizeof(c));
       if(c=='q')
           break;
      
   }
  
    return 0;
}

 

【读端】

首先通过access判断管道文件是否存在,如果不在,那么mkfifo创建一个管道文件。

然后,不断的通过read从管道读取字符,并显示。

当接收的字符为'q'时,结束程序

 

int main(int argc, char *argv[])
{
    int i, ret, fd;
    char p_flag = 0;
    if (access("./myfifo", 0) < 0) {   //先判断有名管道文件是否存在,不存在需要先创建
        ret = mkfifo("./myfifo", 0777);  //权限
        if (ret < 0) {
           cout<<"create fifo error"<

 

 

g++ write.cpp -o write
g++ read.cpp -o read

 

Linux进程间通信②:有名管道FIFO_第2张图片

 

分别启动写入端程序,读取端程序,运行结果:

Linux进程间通信②:有名管道FIFO_第3张图片

 

由此可见,有名管道 named pipe 其主要特点是:

  1. 提供了一种多进程之间通信的方式,本质是多进程读取同一片内存缓冲区。
  2. 相较于匿名管道,由于采取了文件名标识,可以在不是父子进程关系之间通信。
  3. 对管道的读写操作与其它文件操作类似,Linux通过VFS进行抽象统一描述。(一切IO皆是文件思想)