Linux——缓冲区与FLIE*的原理简单实现
发布日期:2025-04-07 11:14:21 浏览次数:6 分类:精选文章

本文共 1934 字,大约阅读时间需要 6 分钟。

Linux——缓冲区与FILE*的原理简单实现

我们最近在学习Linux的文件描述符分配规则时,接触到了缓冲区这一概念。今天,我们将深入探讨这一关键机制的工作原理以及如何实现一个简单的FILE*接口。

缓冲区的概念

缓冲区是操作系统用于临时存储数据的内存区域。它的主要目的是解决I/O操作效率低下的问题。想象一下,系统面对大量向文件输入输出的操作,如果每次都直接将数据送往文件,操作系统的负载会变得极大。而设置一个缓冲区,等到数据积累到一定量后才一次性将其传输到文件中,这样可以显著提升系统性能。

其实,缓冲区的核心作用就是提高效率。通过减少直接操作I/O的频率,缓冲区帮助系统避免了过多的I/O操作,对整体性能产生了积极影响。

##缓冲区的刷新机制

缓冲区的刷新方式主要有三种:

  • 无缓冲:数据直接输入输出,不经过缓冲区。
  • 行缓冲:以换行符为标识单位,遇到换行符时刷新缓冲区。
  • 全缓冲:当缓冲区被填满时立即刷新。
  • 除此之外,还有一些特殊情况会触发缓冲区刷新:

  • 强制刷新 (fflush):通过调用fflush函数强制刷新缓冲区。
  • 进程结束:进程退出时,系统会自动刷新所有缓冲区,确保数据被持久化存储。
  • 一个奇怪的现象

    让我带你看一个有趣的现象:

    // C语言接口fprintf(stdout,"C->fprintf:hello My Love\n");printf("%s","C->printf:hello My Love\n");const char* s = "C->fputs:hello My Love\n";fputs(s,stdout);const char* s1 = "system call:hello My Love\n";write(1,s1,strlen(s1));fork(); // 创建子进程

    当我们将输出重定向到log.txt时,发现C语言接口的输出被重复了两次,而系统调用的输出只被打印了一次。这是为什么呢?

    这背后隐藏着一个重要的概念:C语言为我们提供了一个用户缓冲区。通常情况下,缓冲区的刷新方式是基于我们提供的这个缓冲区(用户缓冲区)来进行的。

    用户级缓冲区与内核缓冲区

    在探讨缓冲区时,用户级和内核级缓冲区是两个需要区分的概念。

  • 用户级缓冲区

    • 由程序员在用户空间显式创建和管理。
    • 存在于用户空间,上行程不能直接访问。
    • 使用标准库函数(如readwrite)进行操作。
    • 更灵活,但需要程序员主动管理。
  • 内核缓冲区

    • 由操作系统内核管理,是内核的一部分。
    • 可能对多个进程可见,通过系统调用进行交互。
    • 内核优化管理,通常用于提高I/O操作效率。
    • 使用readwrite等系统调用的数据传递。
  • 实现简易版本的FILE*

    基于上述机制,我们可以尝试实现一个简单的FILE接口。FILE是C语言中用于表示文件或其他I/O设备的指针,通过它可以进行读写操作。

    #include 
    #include
    #include
    #include
    #include
    int mainOrDefault(int argc, char **argv) { int fd; struct Winsize ws; // 打开指定的设备文件 if (argc >= 2) { fd = open(*argv, O_RDWR | O_NDLCK); if (-1) { fprintf(stderr, "Could not open device %s\n", *argv); return -1; } } else { fd = 1; // 标准输出 } // 获取终端窗口大小 ws.size = sizeof(Winsize); ioctl(fd, TIOGWINSZ, &ws); while(1) { sleep(1); printf("Written: %d bytes\n", ws.write_pointer); } return 0;}

    在本例中:

  • 开口设备文件:使用open系统调用打开指定设备文件或标准输出。
  • 获取窗口大小:通过ioctl函数获取终端窗口大小。
  • 循环写入:睡眠一秒后打印当前缓冲区写指针位置。
  • 通过这个过程,我们可以直观地看到用户缓冲区在I/O操作中的重要作用。

    上一篇:Linux——进程地址空间
    下一篇:Linux——磁盘和文件系统(一)

    发表评论

    最新留言

    做的很好,不错不错
    [***.243.131.199]2025年05月14日 17时55分40秒