国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

理解緩沖區(qū)

這篇具有很好參考價值的文章主要介紹了理解緩沖區(qū)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一.緩沖區(qū)

int main()
{
	printf("hello linux");
	sleep(2);
	return 0;
}

對于這樣的代碼,首先可以肯定的是printf語句先于sleep執(zhí)行,既然如此那么就應該是先打印語句然后進行休眠,下面看看結(jié)果:

理解緩沖區(qū)

但這里卻是先休眠以后再打印語句,這是因為存在一個叫緩沖區(qū)的東西,當我們要向外設寫入數(shù)據(jù)(讓顯示器顯示就是向顯示器寫入數(shù)據(jù))時會將數(shù)據(jù)暫存至緩沖區(qū),然后在根據(jù)緩沖區(qū)的刷新策略刷新。

先休眠再顯示數(shù)據(jù)是因為我們并不是直接向外設寫入數(shù)據(jù),而休眠以后還能刷出數(shù)據(jù)是因為有緩沖區(qū)暫存數(shù)據(jù)。下面就來談談緩沖區(qū)。

1.什么是緩沖區(qū)

緩沖區(qū)的本質(zhì)就是一塊內(nèi)存(物理內(nèi)存)

2.緩沖區(qū)的意義

我是一個奇思妙想的手藝人,我有一個好朋友叫泰褲辣。每當我打造出一個東西的時候我都會騎著自行車跨越一百多公里去送給他。后來有一天,快遞行業(yè)興起了,我有新發(fā)明就不用再自己騎著自行車跨越山和大海去給他送了,我只要將我的東西交給快遞點,就可以繼續(xù)回家搞發(fā)明,東西有快遞公司去給我送,這樣就節(jié)省了我大量的時間。

那么我就是進程,我的好朋友泰褲辣就是文件,而我的新發(fā)明就是數(shù)據(jù),緩沖區(qū)就是快遞點。所以說緩沖區(qū)最大意義就在于節(jié)省發(fā)送者的時間,也就是節(jié)省進程的時間。因為外設是一個很慢的東西,當我們訪問外設的時候大部分時間都是在等外設準備好,真正寫入的時間占比很少。如果有緩沖區(qū)的存在,那么進程只要將數(shù)據(jù)交給緩沖區(qū)以后就可以返回去執(zhí)行后續(xù)的代碼,緩沖區(qū)幫進程承擔了等外設準備好的時間代價。

3.緩沖區(qū)的刷新策略

但我去寄快遞,往往都是我將東西交給快遞點一段時間后我的東西才被快遞點發(fā)出,因為如果一有人寄東西快遞點就派車去送這樣效率太低百分百虧錢。但是如果是在淡季,等了很長也沒有多少人寄快遞,快遞點也不會說將你的東西留在他那里好幾個月。而且如果你是寄一輛轎車大小或者等級的東西,快遞點也是會根據(jù)你這個情況單次的將你的快遞發(fā)出。所以雖然快遞公司正常情況下是等貨物累計要一定數(shù)量才發(fā)送,但是也會有特殊情況。

同理,緩沖區(qū)刷新也是一樣,雖然效率最高的是緩沖區(qū)滿了以后再一次將整個緩沖區(qū)中的數(shù)據(jù)刷新出去(又稱全緩沖),但是這個刷新方式只在將數(shù)據(jù)刷新到磁盤文件上的時候才使用。

向顯示器寫入數(shù)據(jù)時,緩沖區(qū)采用的方式是行刷新(行緩沖)。這是因為顯示器是給用戶看的,而我們?nèi)说拈喿x習慣是按行從左到右讀取,計算機本質(zhì)就是給人使用的工具,所以在給顯示器刷新的時候采用行刷新。

除了全緩沖和行緩沖以外,還有一種很少見的刷新方式叫無緩沖,也就是說一有數(shù)據(jù)寫入就立馬刷新出去。比如printf立馬fflush

此外還有兩種特殊的刷新方式:

1.用戶強制刷新

2.進程退出;進程在退出之前為了防止緩沖區(qū)還有數(shù)據(jù)沒被刷新出去導致數(shù)據(jù)丟失會再刷新一次緩沖區(qū)


4.我們目前談論的緩沖區(qū)在哪里

  #include<stdio.h>    
  #include<unistd.h>    
  #include<string.h>    
      
  int main()    
  {    
      
    //先寫一批C語言函數(shù)接口    
    printf("hello printf\n");    
    fprintf(stdout,"hello fprintf\n");    
    fputs("hello fputs\n",stdout);    
      
    //再寫一個系統(tǒng)調(diào)用    
    const char*s="hello write\n";    
    write(1,s,strlen(s));    
  	fork();                                                                                                                                                                                               
    return 0;    
  }    
 

上面的代碼在直接將結(jié)果顯示到屏幕中和將結(jié)果重定向到文件中是兩種不同的結(jié)果:
理解緩沖區(qū)

根據(jù)上圖可以看到,當我們直接將結(jié)果輸出到屏幕上,一共打印了四條語句這很符合我們的推測。但是一旦將這個輸出結(jié)果重定向到文件中,就變成了打印七條語句,其中C語言的函數(shù)接口被打印了兩次。首先這個現(xiàn)象的原因和緩沖區(qū)有關,其次和fork有關。

上述現(xiàn)象可以說明我們目前為止在談論的緩沖區(qū)不在內(nèi)核中,否則系統(tǒng)調(diào)用write也要被打印兩次,那么它就只能在用戶層。要訪問一個文件首先要有這個文件的fd,所以C語言所用的FILE結(jié)構(gòu)體中一定要包含fd,那么今天可以知道FILE結(jié)構(gòu)體中肯定也是有緩沖區(qū)的,否則為什么我們調(diào)用fflush函數(shù)都是傳FILE*呢?上面談論的各種刷新策略也針對的是FILE結(jié)構(gòu)體中的緩沖區(qū)。

上述情況的解釋:

1.因為顯示器是給用戶看的外設,所以必須要符合用戶按行從左到右的閱讀習慣,也就是說向顯示器文件中寫入時采用的是行刷新,一旦遇到\n就果斷刷新,而向文件中刷新數(shù)據(jù)為了效率采用的是全緩沖,雖然四條輸出語句都帶了\n,但是仍然不足以將緩沖區(qū)寫滿。

2.fork創(chuàng)建的子進程是對父進程的一種拷貝,它們共享代碼和數(shù)據(jù)(包括FILE中的緩沖區(qū)),fork之后馬上就退出了,進程一旦退出為了防止進程丟失會刷新一次緩沖區(qū),而刷新緩沖區(qū)就是將緩沖區(qū)清空,這本質(zhì)上是一種修改,因為進程具有獨立性,為了不然子進程的行為影響父進程就會發(fā)生寫時拷貝,即子進程復制父進程緩沖區(qū)的數(shù)據(jù)并將其刷新到文件中,隨后父進程退出再將數(shù)據(jù)刷新到文件中。

3.系統(tǒng)調(diào)用用的是fd,沒有FILE結(jié)構(gòu)體,也就沒有FILE所提供的緩沖區(qū)。


5.仿寫FILE

紙上得來終覺淺,絕知此事要躬行。接下來我們就自己通過使用系統(tǒng)調(diào)用接口,來嘗試封裝一下FILE結(jié)構(gòu)體:

5.1myStdio.h
#pragma once                                                                                        #include<unistd.h>                                                                                  #include<assert.h>                                                                                 #include<sys/types.h>                                                                               #include<sys/stat.h>                                                                                   #include<fcntl.h>                                                                                   
#include<assert.h>                                                                                  #include<stdlib.h>                                                                                    
#include<string.h>                                                                                    #include<stdio.h>
//FILE中有緩沖區(qū),刷新方式,以及fd                                                                           
//定義緩沖區(qū)大小                                                                                      
#define SIZE 1024                                                                                      //定義刷新方式                                                                                          
#define SYNC_NOW 1                                                                                 #define SYNC_LINE 2                                                                                   #define SYNC_ALL 3                                                                                      typedef struct FILE_       
{                                                                                           
    int flag;//刷新方式                                                                                       int feilno;//fd                                                                                         int cap;//記錄緩沖區(qū)容量                                                                                   int size;//記錄緩沖區(qū)使用
  char buff[];//緩沖區(qū)                                                                                  }FILE_;                                                                                        
//實現(xiàn)四個函數(shù):fopen,fflush,fwrite,fclose        
FILE_*fopen_(const char*path,const char*mode);                                                           void fflush_(FILE_*fp);                                                                               void fwrite_(const char*ptr,size_t num,FILE_*fp);                                                       void fclose_(FILE_*fp);                                                                          
5.2myStdio.c
#include"myStdio.h"
//實現(xiàn)四個函數(shù)


FILE_ *fopen_(const char*path,const char*mode)
{
  int flags=0;//設置文件打開的方式
  int defaultmode=0666;//設置文件打開的默認權(quán)限

  if(strcmp(mode,"r")==0)
  {
    flags|=O_RDWR;
  }
  else if(strcmp(mode,"w")==0)
  {
    flags|=O_WRONLY|O_CREAT|O_TRUNC;
  }
  else if(strcmp(mode,"a")==0)
  {
    flags|=O_WRONLY|O_CREAT|O_APPEND;
  }
  int fd=0;

  if(flags&O_RDWR)
    fd=open(path,flags);
  else
   fd=open(path,flags,defaultmode);

  if(fd<0)//文件打開失敗
  {
    perror("open");
    return NULL;
  }

  FILE_*fp=(FILE_*)malloc(sizeof(FILE_));//為FILE_結(jié)構(gòu)體開辟空間
  assert(fp);
  //初始化FILE_
  fp->cap=SIZE;
  fp->feilno=fd;
  fp->flag=SYNC_LINE;//默認設為行刷新
  fp->size=0;

  memset(fp->buff,0,SIZE);
  return fp;

}

void fwrite_(const char*ptr,size_t num,FILE_*fp)
{
  //將字符串拷貝到緩沖區(qū)
  memcpy(fp->buff+fp->size,ptr,num);
  //更新緩沖區(qū)使用量
  fp->size+=num;

  //按照刷新方式刷新
  if(fp->flag&SYNC_NOW)
  {
    write(fp->feilno,fp->buff,fp->size);
    fp->size=0;
  }
  else if(fp->flag&SYNC_ALL)
  {
    if(fp->size==fp->cap)
    {
      write(fp->feilno,fp->buff,fp->size);
      fp->size=0;
    }
  }
  else if(fp->flag&SYNC_LINE)
  {
    if(fp->buff[fp->size-1]=='\n')//如果最后一個字符是\n
    {

      write(fp->feilno,fp->buff,fp->size);
      fp->size=0;
    }
  }
  
}

void fflush_(FILE_*fp)
{
  //所謂刷新,不過就是將緩沖區(qū)中的內(nèi)容刷新到外設中,有內(nèi)容才刷新
  if(fp->size>0)
    write(fp->feilno,fp->buff,fp->size);
  
  fsync(fp->feilno);//強制刷新到磁盤
  //刷新完以后緩沖區(qū)就沒數(shù)據(jù)了,要將緩沖區(qū)置空
  fp->size=0;
}

void fclose_(FILE_*fp)//在關閉文件之前,還要刷新緩沖區(qū)
{

  fflush_(fp);
  close(fp->feilno);
}

6.操作系統(tǒng)的緩沖區(qū)

不止用戶層有緩沖區(qū),內(nèi)核中也有一個內(nèi)核緩沖區(qū)。當我們使用C語言文件操作函數(shù)寫入數(shù)據(jù)時,首先將數(shù)據(jù)拷貝到FILE結(jié)構(gòu)體的緩沖區(qū)中,并按照無緩沖/行緩沖/全緩沖的刷新策略將數(shù)據(jù)刷新到內(nèi)核緩沖區(qū)中,最后由操作系統(tǒng)自主將內(nèi)核緩沖去中的數(shù)據(jù)刷新到磁盤中。

與其將fwrite等函數(shù)理解成寫入函數(shù),不如將其理解成拷貝函數(shù)

理解緩沖區(qū)

如果你要強制將內(nèi)核緩沖區(qū)中的數(shù)據(jù)刷新到外設中,可以使用系統(tǒng)調(diào)用fsync。文章來源地址http://www.zghlxwxcb.cn/news/detail-425269.html

到了這里,關于理解緩沖區(qū)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 用Linux的視角來理解緩沖區(qū)概念

    用Linux的視角來理解緩沖區(qū)概念

    緩沖區(qū)(buffer)是存儲數(shù)據(jù)的臨時存儲區(qū)域。當我們用C語言向文件中寫入數(shù)據(jù)時,數(shù)據(jù)并不會直接的寫到文件中,中途還經(jīng)過了緩沖區(qū),而我們需要對緩沖區(qū)的數(shù)據(jù)進行刷新,那么數(shù)據(jù)才算寫到文件當中。而緩沖區(qū)通常是一塊內(nèi)存區(qū)域,可以是數(shù)組、隊列、鏈表等數(shù)據(jù)結(jié)構(gòu)。

    2024年01月20日
    瀏覽(23)
  • Linux文件系列: 深入理解緩沖區(qū)和C標準庫的簡單模擬實現(xiàn)

    Linux文件系列: 深入理解緩沖區(qū)和C標準庫的簡單模擬實現(xiàn)

    至此,我們理解了緩沖區(qū)的概念和作用,下面我們來簡易模擬實現(xiàn)一下C標準庫 我們要實現(xiàn)的是: 1.文件結(jié)構(gòu)體的定義 1.首先要有一個文件結(jié)構(gòu)體: 刷新策略分別宏定義為 2.myfopen等等函數(shù)的聲明 path:文件路徑+文件名 mode:打開文件的方式 “r”:只讀 “w”:覆蓋寫 “a”:追加寫 strea

    2024年03月11日
    瀏覽(18)
  • [Linux]理解文件系統(tǒng)!動靜態(tài)庫詳細制作使用?。ň彌_區(qū)、inode、軟硬鏈接、動靜態(tài)庫)

    [Linux]理解文件系統(tǒng)!動靜態(tài)庫詳細制作使用?。ň彌_區(qū)、inode、軟硬鏈接、動靜態(tài)庫)

    ? ? ? ? hello,大家好,這里是bang___bang_,今天來談談的文件系統(tǒng)知識,包含有緩沖區(qū)、inode、軟硬鏈接、動靜態(tài)庫。本篇旨在分享記錄知識,如有需要,希望能有所幫助。 目錄 1??緩沖區(qū) ??緩沖區(qū)的意義 ??常見緩沖區(qū)刷新策略 ??緩沖區(qū)位置猜想 ??現(xiàn)象猜測 ??現(xiàn)象解

    2024年02月13日
    瀏覽(27)
  • 【看表情包學Linux】文件描述符 | 重定向 Redirection | dup2 函數(shù) | 緩沖區(qū)的理解 (Cache)

    【看表情包學Linux】文件描述符 | 重定向 Redirection | dup2 函數(shù) | 緩沖區(qū)的理解 (Cache)

    ?? ??? 爆笑 教程 ????《看表情包學Linux》?? ? 猛戳訂閱 ? ? ?? ?? 寫在前面: 在上一章中,我們已經(jīng)把 fd 的基本原理搞清楚了。本章我們將開始探索 fd 的應用特征,探索 文件描述符的分配原則。講解重定向,上一章是如何使用 fflush 把內(nèi)容變出來的,介紹 dup2 函數(shù),

    2023年04月25日
    瀏覽(19)
  • 理解緩沖區(qū)

    理解緩沖區(qū)

    對于這樣的代碼,首先可以肯定的是 printf 語句先于 sleep 執(zhí)行,既然如此那么就應該是先打印語句然后進行休眠,下面看看結(jié)果: 但這里卻是先休眠以后再打印語句,這是因為存在一個叫緩沖區(qū)的東西,當我們要向外設寫入數(shù)據(jù)(讓顯示器顯示就是向顯示器寫入數(shù)據(jù))時會將

    2023年04月25日
    瀏覽(22)
  • 【Linux】文件緩沖區(qū)

    【Linux】文件緩沖區(qū)

    提到文件緩沖區(qū)這個概念我們好像并不陌生,但是我們對于這個概念好像又是模糊的存在腦海中,之間我們在介紹c語言文件操作已經(jīng)簡單的提過這個概念,今天我們不妨深入理解什么是文件緩沖區(qū) 通過自己實現(xiàn)庫中的一些文件操作函數(shù)更加深入的理解文件緩沖區(qū) 自定義實現(xiàn)

    2024年02月10日
    瀏覽(25)
  • 【C語言趣味教程】(8) 標準 IO 流:輸入和輸出 | 標準輸入 stdin | 標準輸出 stdout | 詳解 printf 和 scanf | 探討 scanf 緩沖區(qū)問題和安全性問題

    【C語言趣味教程】(8) 標準 IO 流:輸入和輸出 | 標準輸入 stdin | 標準輸出 stdout | 詳解 printf 和 scanf | 探討 scanf 緩沖區(qū)問題和安全性問題

    ??? ?? 《C語言趣味教程》?? 猛戳訂閱?。?! 0x00 引入:I/O 的概念 計算機中的輸入和輸出,簡稱 ,其中: ?代表 Input,即輸入。

    2024年02月09日
    瀏覽(27)
  • 【linux】重定向+緩沖區(qū)

    【linux】重定向+緩沖區(qū)

    自我名言 : 只有努力,才能追逐夢想,只有努力,才不會欺騙自己。 喜歡的點贊,收藏,關注一下把! close(1),為什么沒有打印新建文件fd呢? printf(“%dn”,fd); printf會把內(nèi)容打印到stdout文件中。 但是close(1)關閉標準輸出stdout—顯示器,int fd=open();新打開的文件fd是1。 st

    2024年02月08日
    瀏覽(22)
  • 淺談linux緩沖區(qū)的認識!

    淺談linux緩沖區(qū)的認識!

    今天來為大家分享一波關于緩沖區(qū)的知識!那么既然我們要談緩沖區(qū),那么就得從是什么?為什么?有什么作用這幾個方面來談論一下緩沖區(qū)!然后再通過一些代碼來更加深刻的理解緩沖區(qū)的知識! 從最簡單的理解方面來,我們可以將緩沖區(qū)理解成一塊內(nèi)存!那么這塊內(nèi)存是

    2024年02月05日
    瀏覽(20)
  • [Linux打怪升級之路]-緩沖區(qū)

    [Linux打怪升級之路]-緩沖區(qū)

    前言 作者 : 小蝸牛向前沖 名言 : 我可以接受失敗,但我不能接受放棄 ? ?如果覺的博主的文章還不錯的話,還請 點贊,收藏,關注??支持博主。如果發(fā)現(xiàn)有問題的地方歡迎?大家在評論區(qū)指正 ?本期學習目標:認識什么是緩沖區(qū),緩沖區(qū)在哪里,模擬實現(xiàn)一個簡單的緩

    2024年02月07日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包