[linux]:匿名管道和命名管道(什么是管道,怎么创建管道(函数),匿名管道和命名管道的区别,代码例子)

目录

一、匿名管道

1.什么是管道?什么是匿名管道?

2.怎么创建匿名管道(函数)

3.匿名管道的4种情况

4.匿名管道有5种特性

5.怎么使用匿名管道?匿名管道有什么用?(例子)

二、命名管道

1.什么是命名管道?

2.怎么创建命名管道(函数)?

3.命名管道的打开规则

4.怎么使用命名管道?命名管道有什么用?(例子)

三、匿名管道和命名管道的区别


一、匿名管道

1.什么是管道?什么是匿名管道?

我们把从一个进程连接到另一个进程的一个数据流称为一个"管道"。而匿名管道顾名思义,就是一种没有名字的"管道"。

2.怎么创建匿名管道(函数)

#include <unistd.h>

功能:创建一无名管道

原型

int pipe(int fd[2]);

参数

fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端

记忆方法:0像一张嘴,所以是读端,1像一支笔,所以是写端

返回值:成功返回0,失败返回错误代码

3.匿名管道的4种情况

1.正常情况,如果管道没有数据了,读端必须等待,直到有数据为止(写端写入数据了)

2.正常情况,如果管道被写满了,写端必须等待,直到有空间为正(读端读走数据)

3.写端关闭,读端一直读取,读端会读到read返回值为0,表示读到文件结尾

4.读端关闭,写端一直写入,OS会直接杀掉写端进程,通过向目标进程发送SIGPIPE(13)信号,终止目标进程

b.管道的5种特性

1.匿名管道,可以允许具有血缘关系的进程之间进行进程间通信,常用与父子,仅限于此

2.匿名管道,默认给读写端要提供同步机制 ---了解现象就行

  1. 面向字节流的---了解现象就行

4.管道的生命周期是随进程的

5.管道是单向通信的,半双工通信的一种特殊情况

4.匿名管道有5种特性

1.匿名管道,可以允许具有血缘关系的进程之间进行进程间通信,常用与父子,仅限于此

2.匿名管道,默认给读写端要提供同步机制

  1. 面向字节流的

4.管道的生命周期是随进程的

5.管道是单向通信的,半双工通信的一种特殊情况

5.怎么使用匿名管道?匿名管道有什么用?(例子)

例子:

先创建管道, 进而创建子进程, 父子进程使用管道进行通信

父进程向管道当中写"i am father",

子进程从管道当中读出内容, 并且打印到标准输出(屏幕)

cpp 复制代码
#include <unistd.h>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
    int fd[2];
    //打开匿名管道
    if(pipe(fd) == -1)
    {
        cout << "open pipe fail" << endl;
        exit(1);
    }
    pid_t id = fork();
    if(id == 0)//child
    {
        char message[30];
        read(fd[0], message, sizeof(message));

        cout << message << endl;
    }
    //father
    char s[] = "i am father";
    write(fd[1], s, sizeof(s));

    return 0;
}

运行后:

二、命名管道

1.什么是命名管道?

匿名管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信

如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。命名管道是一种特殊类型的文件。

2.怎么创建命名管道(函数)?

命名管道可以从命令行上创建,命令行方法是使用下面这个命令

mkfifo filename

命名管道也可以从程序里创建,相关函数有

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char *filename,mode_t mode);

filename:命名管道的名字

mode:权限值

返回值:成功返回0,失败返回-1

3.命名管道的打开规则

如果当前打开操作是为读而打开FIFO时

  • O_NONBLOCK (disable):阻塞直到有相应进程为写而打开该FIFO
  • O_NONBLOCK (enable):立刻返回成功

如果当前打开操作是为写而打开FIFO时

  • O_NONBLOCK (disable):阻塞直到有相应进程为读而打开该FIFO
  • O_NONBLOCK (enable):立刻返回失败,错误码为ENXIO

4.怎么使用命名管道?命名管道有什么用?(例子)

创建出来的命名管道可以供两个进程通信

进程A 向管道当中写 "i am process A"

进程B 从管道当中读 并且打印到标准输出

processA.cc

cpp 复制代码
#include "fifo.h"
using namespace std;
bool MakeFifo()
{
    int n = mkfifo(FIFONAME, 0644);
    if(n < 0)
    {
        cout << "mkfifo fail" << endl;
        return false;
    }
    return true;
}

int main()
{
    //创建命名管道
    if(!MakeFifo())
    {
        cerr << "mkfifo fail" << endl;
        return 1;
    }
    //打开fifo文件写
    int wfd = open(FIFONAME, O_WRONLY);
    if(wfd < 0)
    {
        cerr << "open fifo fail" << endl;
        return 2;
    }
    cout << "Process A is sending a message to process B" << endl;
    char message[] = "i am process A";
    write(wfd, message, sizeof(message));

    return 0;
}

processB.cc

cpp 复制代码
#include "fifo.h"
using namespace std;

int main()
{
    //打开fifo文件写
    int rfd = open(FIFONAME, O_RDONLY);
    if(rfd < 0)
    {
        cerr << "open fifo fail" << endl;
        return 2;
    }
    cout << "receives messages from process A: ";
    char message[30];
    read(rfd, message, sizeof(message));
    
    cout << message << endl;
    
    return 0;
}

fifo.h

cpp 复制代码
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream>
#include <cassert>
#include <fcntl.h>
#include <unistd.h>

#define FIFONAME  "fifo"

现象:

三、匿名管道和命名管道的区别

  • 匿名管道由pipe函数创建并打开。
  • 命名管道由mkfifo函数创建,打开用open
  • FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义
相关推荐
别惊鹊2 分钟前
hadoop集群配置-xsync脚本同步环境变量
大数据·linux·hadoop
tanyongxi661 小时前
Linux 中 Git 使用指南:从零开始掌握版本控制
linux·git
攻城狮7号1 小时前
【第九节】windows sdk编程:通用控件的使用
c++·windows·windows编程·windows sdk
UpUpUp……1 小时前
Linux中Gdb调试工具常用指令大全
linux·运维·服务器·笔记
曦月逸霜1 小时前
第十次CCF-CSP认证(含C++源码)
数据结构·c++·算法·ccf-csp
若云止水2 小时前
ngx_conf_read_token
linux·运维·服务器
重生之我在20年代敲代码2 小时前
Linux工具【1】(编辑器vim、编译器gcc与g++)
linux·服务器·编辑器
眠りたいです2 小时前
Linux:利用System V系列的-共享内存,消息队列实现进程间通信
linux·运维·服务器·c++·进程间通信
moz与京2 小时前
【附JS、Python、C++题解】Leetcode面试150题(9)——三数之和
javascript·c++·leetcode
nqqcat~2 小时前
函数的引用/函数的默认参数/函数的占位参数/函数重载
开发语言·c++·算法