命名管道是一种在操作系统中用于进程间通信的机制,它允许不同的进程之间通过管道进行数据交换。与匿名管道相比,命名管道具有更多的灵活性和功能。在本博客中,我们将深入探讨命名管道的概念、用途以及如何在编程中使用它们。
目录
命名管道是一种具有独特标识符(通常是文件路径)的管道。它允许不同进程通过该标识符进行通信。与无名管道不同,命名管道存在于文件系统中,使得它们能够跨越进程和甚至计算机边界进行通信。
1??命名管道可以从命令行上创建,命令行方法是使用下面这个命令
mkfifo filename
?示例演示:
【解释说明】?
??接下来,我准备向文件中写入数据:
【解释说明】??
接下来,我们在尝试一下输出重定向操作:
?【解释说明】??
?接下来,我再改一下代码逻辑,再给大家分析一波:
【解释说明】
2???命名管道也可以从程序里创建,相关函数有:
int mkfifo(const char *filename,mode_t mode);
【解释说明】?
【解释说明】??
?上诉是第一种情况,假设如果又来了一个进程,他也要有自己的文件描述符表,紧接着有一个小问题?
【解释说明】?
【解释说明】??
【注意事项】
不过如果这个文件是一个普通文件,将来你写的时候数据要定期刷新到磁盘里面,可是今天我们的目的是想让这两个进程,通过对应的缓冲区让他们俩之间通信,好让他们俩直接通信,那么我们的文件呢就不应该把这个数据刷到磁盘上,所以未来呢,我们如果创建了一个文件,这种文件必须有一个特性,就叫做是内存级
?【解释说明】??
如果当前打开操作是为读而打开FIFO时
如果当前打开操作是为写而打开FIFO时
【client.cc】
#include <iostream>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <cassert>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "common.hpp"
int main()
{
//1. 不需创建管道文件,我只需要打开对应的文件即可!
int wfd = open(fifoname.c_str(),O_WRONLY);
if(wfd < 0)
{
std::cerr << errno << ":" << strerror(errno) << std::endl;
return 1;
}
//正常通信
char buffer[NUM];
while(true){
system("stty raw");
int c = getchar();
system("stty -raw");
ssize_t n = write(wfd, (char*)&c, sizeof(char));
assert(n >= 0);
(void)n;
}
//关闭不要的fd
close(wfd);
return 0;
}
【server.cc】
#include <iostream>
#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "common.hpp"
int main()
{
// 1. 创建管道文件
umask(0); //这个设置并不影响系统的默认配置,只会影响当前进程
int n = mkfifo(fifoname.c_str(),mode);
if(n != 0)
{
std::cout << errno << " : " << strerror(errno) << std::endl;
return 1;
}
std::cout << "create fifo file success" << std::endl;
// 2.让服务端直接开启管道文件
int rfd = open(fifoname.c_str(), O_RDONLY);
if(rfd < 0 )
{
std::cout << errno << " : " << strerror(errno) << std::endl;
return 2;
}
std::cout << "open fifo success" << std::endl;
// 3.正常通信
char buffer[NUM];
while (true)
{
buffer[0] = 0;
ssize_t n = read(rfd,buffer,sizeof(buffer));
if(n > 0){
buffer[n] = 0;
printf("%c", buffer[0]);
fflush(stdout);
}
else if(n == 0){
std::cout << "client quit, me too" << std::endl;
break;
}
else {
std::cout << errno << " : " << strerror(errno) << std::endl;
break;
}
}
// 4.关闭不要的fd
close(rfd);
unlink(fifoname.c_str());
return 0;
}
【common.hpp】
#pragma once
#include <iostream>
#include <string>
#define NUM 1024
const std::string fifoname = "./fifo";
uint32_t mode = 0666;
以上便是关于命名管道的全部知识内容了,接下来简单小结命名管道以及匿名管道和命名管道之间的区别!!
?命名管道:
基本概念: 命名管道是一种通过文件系统路径标识的通信管道,允许不同进程之间进行通信。
创建方式: 在Unix/Linux系统中,可以使用 mkfifo
函数创建命名管道;在Windows系统中,可以使用 CreateNamedPipe
函数。
通信方向: 命名管道同样是单向的,但可以被用于任意两个进程之间的通信,甚至是不同计算机之间。
生命周期: 命名管道的生命周期不受限于创建它的进程,可以长时间存在于文件系统中。
灵活性: 命名管道相对于匿名管道更灵活,适用于更复杂的进程通信场景,包括跨越进程和计算机的通信。
匿名管道与命名管道的区别:
本文内容便讲解结束,感谢大家的观看和支持!!?
?