【Linux IO基础】缓冲区

devtools/2024/10/18 14:18:29/

概念

缓冲区的主要作用是提高效率 --- 提高使用者的效率,因为有缓冲区的存在,我们可以积累一部分再统一发送,提高发送的效率。

刷新方式

缓冲区因为能够暂存数据,必定要有一定的刷新方式:

一般策略:

  • 无缓冲(立即刷新)

  • 行缓冲(行刷新)

  • 全缓冲(缓冲区满了,再刷新)

特殊情况:

假如快递站是缓冲区,那么如果一直等到缓冲区满了,客人往往会不耐烦,因此也有别的刷新方式:

  • 强制刷新

  • 进程退出的时候,一般要进行刷新缓冲区

    一般对于显示器文件:行刷新(行缓冲)

    对于磁盘上的文件:全缓冲(缓冲写满,再刷新)

示例

可以看到myfile里只有四条打印的代码,但是重定向log里却有七条信息,这是为什么?

  1. 当我们直接向显示器打印的时候,显示器文件的刷新方式是行刷新!而且你的代码 输出所有的字符串,都有\n,fork之前,数据全部已经被刷新,包括syystemcall

  2. 重定向到log.txt,本质是向磁盘文件中写入(不是显示了哦!),我们系统对于数据的刷新方式已经由行刷新,编程了全缓冲!

  3. 全缓冲比意味着缓冲区变大,实际写入的简单数据,不足以把缓冲区写满,fork执行的时候,数据依旧在缓冲区中!

  4. 我们所谈的"缓冲区",和操作系统是没有关系的,只能和C语言本身有关!(因为fprintf/printf/fputs底层都是封装的write)

  5. C/C++提供的缓冲区,里面一定保存的是用户的数据,属不属于当前进程在运行时自己的数据呢?属于! 如果我们把数据交给了操作系统,这个数据就属于操作系统,不属于我自己的。

  6. 当进程退出的时候,一般要进行刷新缓冲区,即便你的数据没有满足刷新条件! ''刷新缓冲区''属于清空或者"写入"操作。

  7. fork立马退出,任意一个进程在退出的时候刷新缓冲区,就要发生写时拷贝!!!而write系统调用,没有使用C的缓冲区,它是直接把数据写入到操作系统,数据也就不属于进程,不发生写时拷贝了!

至于为什么fprintf/printf/fputs命令会因为fork的调用而被再次执行,因为当程序调用fork函数时,操作系统会复制当前进程的内存空间,包括文件描述符和缓冲区。在这种情况下,父进程和子进程共享相同的标准输出缓冲区。因此,当父进程在执行上面三个命令时,这些输出会先被放入共享的缓冲区中,而非write一样被直接输出,当执行fork函数,操作系统会创建一个新的子进程,子进程也会继承父进程的缓冲区内容。

总之,在fork函数执行前,C文件中的四条命令都会将数据写入到log中,而fork执行后,子进程和父进程共享缓冲区,当子进程执行完毕退出时,因为满足特殊情况,所以操作系统会将缓冲区的内容(也就是除了write的三条命令输出的数据)刷新并输出到log文件中,所以在将myfile重定向到log之后,log文件中有7条数据而不是4条。


http://www.ppmy.cn/devtools/36373.html

相关文章

JAVA入门2

前言: 不一样的编程——基于两个大前提,语言随便选一个,作者选java和c,在后续的内容会有c和java的共同使用 第一大前提:编程语言起源于语言 第二大前提:计算机理解不了语言的含义 这两大前提构成了不一样的…

LeetCode:滑动窗口最大值

文章收录于LeetCode专栏 LeetCode地址 滑动窗口最大值 题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。   返回 滑动窗口中的最大值 。   示例 1…

五一 作业

#include <iostream>using namespace std; class Num { private:int a; public:Num() {}Num(int a):a(a){}//设置a的值void set(int a){this->aa;}//1-a的和void Sum(){if(a<1){cout<<"a<1"<<endl;return;}int sum0;for(int i1;i<a;i)…

Raft共识算法图二解释

下面是有关Raft协议中不同术语和概念的翻译及解释&#xff1a; 术语和概念&#xff1a; 任期号&#xff08;term number&#xff09;&#xff1a;用来区分不同的leader。前一个日志槽位的信息&#xff08;prelogIndex&#xff09;&#xff1a;这是前一个日志条目的索引&#…

后端如何处理接口的重复调用

首先是&#xff0c;原理在请求接口之前&#xff0c;使用过滤器拦截数据&#xff0c;来进行判断两次数据是否一致。 1.自定义注解 2.创建一个Handler处理器 3.RepeatSubmitInterceptor的实现类 4.过滤器的配置

翻译《The Old New Thing》- Does Windows have a limit of 2000 threads per process?

Does Windows have a limit of 2000 threads per process? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20050729-14/?p34773 Raymond Chen 2005年07月29日 Windows 是否有一个每个进程2000线程的限制&#xff1f; 简要 文章解释了在 W…

LeetCode 226.翻转二叉树

题目描述 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;[2,3,1]示例…

VBA快速删除Excel工作表

Excel处理数据时,经常需要删除部分工作表,像这样 工作中一个工作薄中十几张甚至几十张工作表是常有的事,手动一张张去删,费时费力,VBA代码可以帮你快速搞定,这就需要非常简单的代码 。 1、如果只留下一张名为“Sheet1”的工作表,其余的全删除,代码如下: For Each She…