当前位置:网站首页>Do you really understand the concept of buffer? Take you to uncover the buffer zone~
Do you really understand the concept of buffer? Take you to uncover the buffer zone~
2022-07-24 09:40:00 【Rabbit 7】


Hello everyone , I am a rabbit 7 , A hard-working C++ Bloggers ~
If there is something wrong with the knowledge of the article , Please correct me. ! Learn with you , Progress together
If you have not understand , You can always ask me questions , I will try my best to explain ~
If you feel the blogger's article is good , I want you to pay attention 、 give the thumbs-up 、 Collect three companies to support bloggers ~!
Your support is the driving force of my creation !
🧸 I believe the hard work now , Are the best witness for the future !
🧸 People's attitude determines posture !
This article CSDN First episode !
Catalog
Preliminary understanding of buffer zone
The meaning of line buffer and full buffer
Preface
For better observation , Here I use Linux Environment to test !
This blog is the information that bloggers will review in the future , So you can rest assured to learn , It's very comprehensive , Each piece of code has been sent to everyone , If you have any questions, you can try debugging .
We must look at the pictures carefully , The words in the picture are all essence , Many details are shown in the picture 、 It's written out , So we must be careful ~
Thank you for your support , Thank you for your love , rabbit 7 I wish you all a smooth journey in your study , Everything goes well on the way of life ~!
buffer
What is the buffer ?
buffer (buffer), It is Part of the memory space . in other words , A certain amount of storage space is reserved in the memory space , This storage space is used to buffer input or output data , This part of the reserved space is called a buffer , Obviously the buffer is of a certain size . The buffer depends on whether it corresponds to an input device or an output device , Divided into input buffer and output buffer .
Why introduce buffers ?
The mismatch between high-speed equipment and low-speed equipment , It's bound to make high-speed devices spend time waiting for low-speed devices , We can set up a buffer between the two .
- It can remove the restriction between the two , Data can be sent directly to the buffer , High speed devices no longer have to wait for low speed devices , Improve the efficiency of the computer . for example : We use printers to print documents , Because the printer's printing speed is relatively slow , Let's first output the document to the corresponding buffer of the printer , The printer then prints itself step by step , That's when our CPU Can deal with other things .
- Can reduce the number of data read and write , If only a little bit of data is transmitted at a time , It needs to be transmitted many times , It will waste a lot of time , Because it takes a long time to start and stop reading and writing , If you send data to a buffer , Waiting for the buffer to be full before transferring will greatly reduce the number of reads and writes , This can save a lot of time . for example : We want to write data to disk , Instead of writing data to disk right away , It's in the buffer first , When the buffer is full , Then write the data to disk , This can reduce the number of disk reads and writes , Otherwise, the disk will break easily .
Simply speaking , A buffer is a block of memory , It's used in I / O devices and CPU Between , Used to store data . It makes low-speed I / O devices and high-speed CPU Ability to coordinate work , Avoid low speed I / O devices CPU, Liberate CPU, Make it work efficiently .
Preliminary understanding of buffer zone

In this code , We can see that it is printed first "hello world" after , Sleep 3 second , Then terminate the program .
But if we remove "hello world" final "\n" Well ? Print first "hello world" Or sleep first ?
Let's test it first :

What we see is sleep first , And then print it "hello world" , It's not , Anyway , Always print first "hello world" , It's just "hello world" It is temporarily stored in buffer in . therefore , When we run , It seems to run first sleep(3) , Finally refresh "hello world" .
buffer :
- No buffer
- The line buffer ( It is common to refresh data on the display )
- Full buffer ( The file ( It can be understood as a disk file ) Use full buffer when writing )
Memory line buffer means : When used printf When printing , If there is "\n" Then put "\n" And the previous content is immediately refreshed on the display . without "\n" Then the memory line buffer will not be refreshed until it is full .
These are also the two situations we demonstrated above .
Full buffer means : The full buffer must be filled before it is flushed to the disk file , Otherwise, it will not refresh .
The meaning of line buffer and full buffer
Have you ever thought about it , Why is the monitor line buffer , The file is fully buffered ?
Because computers follow the von Neumann system , Therefore, the file itself belongs to peripherals in the system , Or it belongs to peripherals , for instance : The keyboard is a peripheral 、 Disks are peripherals ... ...
let me put it another way , If we want to refresh the data to disk , Or refresh to the display , In fact, they are all called writing on peripherals , And everyone should know , Writing directly to peripherals is inefficient , So we accumulate the data into the buffer , When you accumulate enough, refresh regularly , In this way, the efficiency will be improved a lot .
So theoretically , In fact, the efficiency of full buffer is the highest . So is the line buffer of the display meaningless ?
Of course not. , It's understandable , The files on our disk , At the time of writing , People can't read , The monitor is different , The display is when a person writes data , This person wants to get the corresponding output results as soon as possible , Then we need to use the row buffer to refresh .
Is it better to use no buffer in this way ? Of course not ~ Because if there is no buffer , It's too inefficient , Because unbuffered efficiency is too low , Full buffer people don't see the data in time .
So line buffering is actually a balance between efficiency and availability in unbuffered and full buffering !
Where is the buffer ?
Who provides the buffer ?
Before we talk about it , First, we need several groups of data to test :

We can see , Whether it's C Functions provided by language , still Linux Function of , Can print normally . So if we add a before the return fork() Well ? That is to create sub processes ?

We can see , Printing is normal , But we added fork() after , When writing in the file , Found that the content has changed !
Combined with what we said above, let's sort it out first :

We will find that , "hello write" It's only printed once , and "hello printf" and "hello fprintf" Printed twice .
So we can draw two conclusions :
- Redirection or not will change the buffering method of the process .
- C The interface was called twice ,OS API Once .
In fact, you may doubt ,fork() In the end , because fork() Is it to create a child process , because fork() What should have been printed before has been printed , Something tells me ,fork() It doesn't make sense .( Because I think so !)
however ! Although you have finished , But have you refreshed all of them ? Is it all displayed ? The answer is not necessarily !

Here is a picture , I'll string it again :
Because one is to hit the monitor , One is to write in the document , So the buffering method will change , Write it on the monitor because "\n" So refresh directly after printing , That is to say, it will be finished directly , So it's in fork() After that, there was no data , So the last print is three lines .
But when we redirect , That is, write from the file , It becomes a full buffer , After becoming full buffer, we just write from full buffer , That is, only printing is completed , But the data is not refreshed , Because the refresh condition is not satisfied .(1. The buffer is not full 2. The program did not exit ) So the program continues to run , At this time in fork() When , Because the buffer itself is the memory area corresponding to the process , That is, the data of the parent process , therefore fork() When , Refresh the parent process or child process , That is, write , Then write time copy will occur , That is, the parent process or child process will copy the same data , Finally, after the program exits , At this time, it is refreshed twice , So the last thing I saw was this phenomenon !
But why do we use write Didn't print twice ?
First, let's talk about why we print twice :
- buffer
- Copy on write occurred
Copy on write will always happen , Because it is written inside the operating system , So why print twice , The essence is the existence of buffer !
The system call we use does not print twice , in other words write( system call ) There is no buffer !
Because in fork() After that, although write time copying occurred , But because there is no buffer , So the data has already been brushed out .
So how to understand C Function has buffer , And the system call has no buffer ?
Conclusion :
because C Library functions are a layer of encapsulation on system calls , So explain The buffer is C The language comes with ( Provided )!
So in C When the language realizes here struct FILE Inside is existence fd( File descriptor ) and User buffer , That is to say stay struct FILE in Of .
So actually C Language 、C++ In fact, there are buffers , So the data in the buffer is like pipelining , Flow in from the program , Brush it out regularly , So we call it file flow .
OS The buffer vs File buffer


We found that , When we follow the way shown in the left figure , close 1 , And then finally fflush(stdout) Can be written in , What if we just print without refreshing ?

We will find that , Three prints have not been refreshed , So why not ? Why do I have to bring fflush Well ? We knew that before , If you print it on the screen , If you don't refresh manually , The buffer will be refreshed automatically after the process ends , So why is this ?
Because at this time printf The file has been redirected when printing , It's not printed from the screen , It has been written from the file , So its buffer mode has changed from line buffer to full buffer , So the final data is stored in the buffer of the user area , If you do not force refresh , That is to say fflush(stdout) , Because the buffer is not full , So it will not be refreshed into the kernel . So when it doesn't refresh , And there is no fflush(stdout) when , Who was the last one we closed ?
The last thing we closed was fd ! We are not calling fclose(stdout) !fd Who is it? ?fd yes FILE File descriptor used at the bottom of the file , let me put it another way , This data is in the user buffer , Finally, when the process ends, it also wants to refresh , But found fd It's off , So there is no way to refresh , So the last data is always in the buffer of the user area , Finally, it was not refreshed into the kernel , Then it will not show .
So if we use C Linguistic fclose(stdout) ,C Linguistic fclose(stdout) It's off stdout , stdout Standard output , The bottom layer of standard output is 1 File descriptor , therefore fclose(stdout) When , That is, close the file , The operation that must be done is to brush the data into the kernel , Then the process exits , So there will be data finally .
Let's demonstrate fclose(stdout) :

We can see the refresh !
I'll say it again : We open the file with a system call , When printing, use C Language , and C Used in language stdout The file descriptor inside is 1 you 're right . But when we close the file, we close the file first , Then the program exits , In other words, when we print , Because of reshaping , So the buffer refresh method has changed , It is fully buffered , So the data will be temporarily stored and then C In the buffer of user area in language , But the process has to be refreshed when it exits , But when my process exits , If you adjust close ,close It's a stdout The corresponding file descriptor is turned off , When the process exits, you can't brush it if you want to , So there is no way to refresh the data left in the user buffer to the file pointed to by the underlying process , So in the end, there is no way to refresh . So what we need to close is fclose(stdout) , This gives the buffer of the user area a chance to refresh , You can brush the bottom layer .
So if we neither fclose either close Well ?

We can see , It will be refreshed .
Actually, let's think about it ,FILE The object is our application , When the process exits , The resources once applied for should be returned to the operating system , Now that you return the operating system , So the operating system should refresh all the resources you apply for , Full release to be released , So the final No close either fclose , Finally, it can still be written into the file , Because when the process exits , The operating system will refresh the data .

That's it buffer All the knowledge of , If you like reading this article and have some harvest , You can support rabbit 7 , to rabbit 7 Pay more attention for three times , Your attention is my greatest encouragement , It is also my creative motivation ~!
Thank you again for watching , Thank you for your support !
边栏推荐
- Opencv learning Day5
- One year after I came to Ali, I ushered in my first job change
- PHP debugging tool - how to install and use firephp
- Asyncdata cross domain error after nuxt route switching
- Aruba学习笔记06-无线控制AC基础配置(CLI)
- [assembly language practice] (II). Write a program to calculate the value of expression w=v- (x+y+z-51) (including code and process screenshots)
- Es search summary
- JS locate Daquan to get the brother, parent and child elements of the node, including robot instances
- Android Version Description security privacy 13
- Spark Learning: using RDD API to implement inverted index
猜你喜欢
![[MySQL] - deep understanding of index](/img/a6/6ca1356fe11bd33ec7362ce7cdc652.png)
[MySQL] - deep understanding of index

配置系统环境变量的时候误删了Path怎么办?

2022 trusted cloud authoritative assessment released: Tianyi cloud has obtained ten certifications and five best practices

gnuplot软件学习笔记

Linux deployment mysql8.0

This article takes you to understand the dynamic memory allocation of C language

Android Version Description security privacy 13

Gnuplot software learning notes

Re6: reading paper licin: a heterogeneous graph based approach for automatic legal stat identification fro

Will your NFT disappear? Dfinity provides the best solution for NFT storage
随机推荐
2021 robocom world robot developer competition - undergraduate group (Preliminary) problem solution
S2b2b system standardizes the ordering and purchasing process and upgrades the supply chain system of household building materials industry
SQL 优化原则
Little dolphin "transformed" into a new intelligent scheduling engine, which can be explained in simple terms in the practical development and application of DDS
[example] v-contextmenu right click menu component
数据中台:始于阿里,兴于DaaS
Gin framework uses session and redis to realize distributed session & Gorm operation mysql
Asyncdata cross domain error after nuxt route switching
Common evaluation indexes of medical image segmentation
Detailed explanation of the whole process of R & D demand splitting | agile practice
Spark Learning: how to choose different association forms and mechanisms?
PHP Basics - PHP types
Tiflash source code reading (V) deltatree storage engine design and implementation analysis - Part 2
Get the historical quotation data of all stocks
获取所有股票历史行情数据
What does CRM mean? Three "key points" for CRM management software selection
Makefile variables and dynamic library static library
The next stop of data visualization platform | gifts from domestic open source data visualization datart "super iron powder"
Getting started with sorting - insert sorting and Hill sorting
[assembly language practice] (II). Write a program to calculate the value of expression w=v- (x+y+z-51) (including code and process screenshots)