当前位置: 首页 > news >正文

命名管道 vs 匿名管道的内核缓冲区区别

命名管道 vs 匿名管道的内核缓冲区区别

1. 生命周期和管理方式

匿名管道缓冲区:

int pipefd[2];
pipe(pipefd);  // 创建匿名管道
  • 临时性:缓冲区随管道的创建而创建,当所有引用它的文件描述符关闭时自动销毁
  • 进程绑定:缓冲区生命周期与使用它的进程组绑定
  • 自动管理:内核在不再需要时自动回收缓冲区

命名管道缓冲区:

mkfifo("/tmp/myfifo", 0666);  // 创建命名管道文件
  • 持久性:缓冲区与文件系统节点关联,不依赖于单个进程
  • 文件系统绑定:缓冲区生命周期与管道文件绑定
  • 显式管理:需要手动删除管道文件来完全释放资源

2. 缓冲区的创建时机

匿名管道:

  • pipe() 系统调用时立即创建内核缓冲区
  • 缓冲区大小固定(通常为 64KB)

命名管道:

  • mkfifo() 时只创建文件系统节点,不立即分配完整缓冲区
  • 实际的内核缓冲区在第一次有进程打开管道时才完全初始化

3. 缓冲区的共享范围

匿名管道:

// 只能在相关进程间共享
if (pipe(pipefd) == 0) {pid_t pid = fork();if (pid == 0) {// 子进程继承相同的缓冲区引用close(pipefd[1]);read(pipefd[0], buffer, size);}
}

命名管道:

// 任何知道路径的进程都可以访问
// 进程A
int fd1 = open("/tmp/myfifo", O_RDONLY);// 进程B(完全无关的进程)
int fd2 = open("/tmp/myfifo", O_WRONLY);

4. 技术实现细节

从Linux内核源码角度看:

匿名管道 (fs/pipe.c):

struct pipe_inode_info *alloc_pipe_info(void)
{struct pipe_inode_info *pipe;pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);if (!pipe)return NULL;// 分配环形缓冲区pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),GFP_KERNEL);// ...
}

命名管道 (fs/fifo.c):

// 复用相同的管道数据结构,但通过不同的文件操作
static const struct file_operations fifo_fops = {.open       = fifo_open,    // 特殊打开处理.llseek     = no_llseek,.read_iter  = pipe_read,.write_iter = pipe_write,// ...
};

5. 缓冲区大小和行为

虽然两种管道都使用类似的内核缓冲区结构,但在行为上有差异:

特性匿名管道命名管道
默认缓冲区大小PIPE_BUF (通常4KB) × 16同匿名管道
最大写入原子性PIPE_BUF 字节同匿名管道
阻塞行为读写端都存在时创建需要显式打开两端
缓冲区分配立即分配延迟分配(首次打开时)

6. 实际验证示例

让我们通过代码验证缓冲区的区别:

缓冲区生命周期测试:

// test_anonymous.c - 匿名管道测试
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>int main() {int pipefd[2];char buffer[100];pipe(pipefd);  // 创建匿名管道和缓冲区pid_t pid = fork();if (pid == 0) {// 子进程close(pipefd[1]);  // 关闭写端read(pipefd[0], buffer, sizeof(buffer));printf("Child read: %s\n", buffer);sleep(5);  // 保持读端打开close(pipefd[0]);_exit(0);} else {// 父进程close(pipefd[0]);  // 关闭读端write(pipefd[1], "Hello", 6);close(pipefd[1]);  // 关闭写端,但子进程仍持有读端wait(NULL);  // 等待子进程结束// 此时所有文件描述符关闭,缓冲区被回收}return 0;
}
// test_named.c - 命名管道测试
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>#define FIFO_FILE "/tmp/test_fifo"int main() {// 创建命名管道(此时可能还没有完整缓冲区)mkfifo(FIFO_FILE, 0666);printf("Named pipe created. Buffer may not be fully allocated yet.\n");// 现在打开管道,触发缓冲区分配int fd = open(FIFO_FILE, O_RDWR);  // 以读写方式打开printf("Pipe opened. Buffer now fully allocated.\n");// 即使关闭,文件系统和潜在的缓冲区结构仍然存在close(fd);printf("File descriptor closed, but pipe file still exists.\n");// 需要显式删除才能完全清理unlink(FIFO_FILE);printf("Pipe file deleted. Resources fully released.\n");return 0;
}

7. 总结

核心区别:

  1. 生命周期管理:匿名管道自动管理,命名管道需要显式管理
  2. 创建时机:匿名管道立即分配,命名管道延迟分配
  3. 共享范围:匿名管道限于相关进程,命名管道全局可访问
  4. 资源绑定:匿名管道绑定进程,命名管道绑定文件系统

底层相似性:

  • 都使用相同的内核数据结构 pipe_inode_info
  • 都使用环形缓冲区管理数据
  • 都有相同的原子写入限制(PIPE_BUF)
  • 都支持相同的阻塞/非阻塞模式
http://www.dtcms.com/a/471028.html

相关文章:

  • 基于MATLAB生成雷达脉冲信号
  • 百度网盘 13.11.4 | 支持倍速播放,去除广告及冗余功能,界面简洁,体积小巧
  • 牛客算法_数组
  • 怎样建立自己购物网站阿里云gpu服务器租用费用
  • 浙江省网站备案时间手机网站开发 宽度
  • 计算学习理论:周志华《机器学习》中的理论基石
  • 怎么做 社区网站首页wordpress报表
  • 建个网站需要多少钱圣宝电动车大架号在哪里做有后台的网站
  • linux学习笔记(26)计算机网络基础
  • 网站建设与维护书籍推荐魔方网站建设网站制作
  • h5网站要多久工商注册名称核准
  • Spring Boot 3零基础教程,依赖管理机制,笔记06
  • 做网站得花多少钱wordpress 百度推广
  • AI在安全运营中的四大价值与制约
  • Node.js 24.10.0: 拥抱现代 JavaScript 与增强性能
  • 1.2、网络安全攻防实验室搭建指南:VMware + Kali Linux + Win10 全流程
  • 网站规划模板下载wordpress导入数据库后出现乱码
  • UPage 正式开源!
  • 网站建设外包工作室建设厅网站首页
  • 07-docker-compose容器编排
  • 网站密钥怎么做百度投诉中心在线申诉
  • 数据库、API和MCP等概念
  • 敬请期待打一生肖seo公司如何优化
  • 怎么做淘宝返利网站wordpress打印文章
  • 内蒙医院BA楼宇自控系统与IBMS集成系统深度解析
  • 站外营销有哪几种主流方式天津智能网站建设哪里有
  • seo网站设计电子商务网站总体规划的内容
  • 做签名的网站购物网站建设项目策划书
  • 盛盾科技网站建设网页设计如何把照片作为背景
  • 成都科技网站建设找本地环说wordpress配置邮箱