告别命令行!用MongoDB Compass可视化工具5分钟搞定数据库日常操作
2026/6/4 17:28:42
/tmp/mypipe),所以任何进程,只要知道这个路径,有权限,就可以通过打开文件的方式来打开它。你可以不写代码,直接在 Linux 终端感受一下。
mkfifoBash
mkfifo mypipeBash
ls -l mypipe # 输出: prw-r--r-- 1 user group 0 ... mypipe注意开头的p,这代表它是一个Pipe文件。
cat mypipeecho "Hello FIFO" > mypipe为了演示“毫无关系”的进程通信,我们需要写两个独立的程序:
server.cpp:负责创建管道,读取数据(读端)。client.cpp:负责打开管道,发送数据(写端)。这其实就是最简陋的服务器-客户端模型。
#include <iostream> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <errno.h> #define FIFO_FILE "./mypipe" int main() { // 1. 创建命名管道 // 参数2:权限掩码 (类似 mkdir) if (mkfifo(FIFO_FILE, 0666) < 0) { if (errno != EEXIST) { // 如果文件已存在,不算错 perror("mkfifo"); return 1; } } std::cout << "Server: FIFO created, waiting for client..." << std::endl; // 2. 打开管道 (读方式) // 注意:这里会【阻塞】,直到有别的进程以写方式打开同一个 FIFO int fd = open(FIFO_FILE, O_RDONLY); if (fd < 0) { perror("open"); return 2; } std::cout << "Server: Client connected!" << std::endl; // 3. 循环读取 char buffer[1024]; while (true) { memset(buffer, 0, sizeof(buffer)); ssize_t s = read(fd, buffer, sizeof(buffer) - 1); if (s > 0) { // 读到数据 std::cout << "Client Say# " << buffer << std::endl; } else if (s == 0) { // 写端关闭了 (Client 退出) std::cout << "Client quit, Server quit." << std::endl; break; } else { perror("read"); break; } } close(fd); return 0; }#include <iostream> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #define FIFO_FILE "./mypipe" int main() { std::cout << "Client: Trying to connect server..." << std::endl; // 1. 打开管道 (写方式) // 只要 Server 端创建了 FIFO,Client 直接打开即可 int fd = open(FIFO_FILE, O_WRONLY); if (fd < 0) { perror("open"); return 1; } std::cout << "Client: Connected! Please enter message:" << std::endl; // 2. 循环写入 std::string line; while (true) { std::cout << "> "; if (!std::getline(std::cin, line)) break; // Ctrl+D 退出 write(fd, line.c_str(), line.size()); } close(fd); return 0; }g++ server.cpp -o server和g++ client.cpp -o client。./server。你会发现它打印完 "waiting for client..." 就卡住了。./client。open的秘密你可能注意到了,Server 在open的时候卡住了。这是命名管道的一个重要特性。
同步规则:
O_RDONLY):会阻塞,直到有另一个进程以写方式打开同一个 FIFO。O_WRONLY):会阻塞,直到有另一个进程以读方式打开同一个 FIFO。为什么这样设计?
这就好比打电话。
open才会同时返回,连接建立成功。这两种管道是 Linux IPC 的基础,我们做一个对比总结:
特性 | 匿名管道 (Pipe) | 命名管道 (FIFO) |
可见性 | 内存中,无文件名 | 磁盘上有文件名 |
通信范围 | 仅限血缘关系进程 (父子/兄弟) | 任意进程 (只要权限允许) |
创建方式 |
|
|
生命周期 | 随进程结束而销毁 | 随文件系统 (即使进程全退出了,文件还在) |
本质 | 都是内核中的一块缓冲区 | 同左 |