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

【Linux】理解緩沖區(qū)

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

一.引入

linux write 怎么查看fd緩沖區(qū),學(xué)好Linux,linux,網(wǎng)絡(luò),運(yùn)維

我們發(fā)現(xiàn) printf 和 fwrite (庫函數(shù))都輸出了2次,而 write 只輸出了一次(系統(tǒng)調(diào)用)。為什么呢?肯定和fork有關(guān)!

C接口的函數(shù)被打印了兩次系統(tǒng)接口前后只是打印了一次:和fork函數(shù)有關(guān),fork會(huì)創(chuàng)建子進(jìn)程。在創(chuàng)建子進(jìn)程的時(shí)候,數(shù)據(jù)會(huì)被處理成兩份,父子進(jìn)程發(fā)生寫時(shí)拷貝,我們進(jìn)行printf調(diào)用數(shù)據(jù)的時(shí)候,數(shù)據(jù)寫到顯示器外設(shè)上,就不屬于父進(jìn)程了,數(shù)據(jù)沒被寫到顯示器上,依舊屬于父進(jìn)程,而調(diào)用printf并不一定把數(shù)據(jù)刷到顯示器上,沒有被顯示本質(zhì)就是數(shù)據(jù)沒有從內(nèi)存到外設(shè),所以這份沒有被顯示的數(shù)據(jù)依舊屬于這進(jìn)程,當(dāng)我們?nèi)ork的時(shí)候,進(jìn)程退出要刷新緩沖區(qū),此時(shí)刷新的過程就是把數(shù)據(jù)從內(nèi)存刷新到外設(shè),刷新到外設(shè)的同時(shí),也會(huì)把程序內(nèi)部的緩沖區(qū)的數(shù)據(jù)直接清走,這就是寫入,跟寫時(shí)拷貝有關(guān)系

對(duì)于這個(gè)現(xiàn)象的問題我們可以直接往下看??


二.認(rèn)識(shí)緩沖區(qū)

1.為什么

緩沖區(qū)的本質(zhì)就是一段內(nèi)存。在內(nèi)存空間中預(yù)留了一定的存儲(chǔ)空間,這些存儲(chǔ)空間用來緩沖輸入或輸出的數(shù)據(jù),這部分預(yù)留的空間就叫做緩沖區(qū)。

數(shù)據(jù)如果直接從內(nèi)存到磁盤,在內(nèi)存中速度快,但是訪問外設(shè)效率比較低,那太消耗時(shí)間了,屬于外設(shè)IO,所以緩沖區(qū)的意義就是節(jié)省進(jìn)程進(jìn)行數(shù)據(jù)IO的時(shí)間!進(jìn)程需要把數(shù)據(jù)拷貝到緩沖區(qū)里:我們并不需要拷貝,而是調(diào)用fwrite,與其理解fwrite是寫入到文件的函數(shù),倒不如理解fwrite是拷貝函數(shù),將數(shù)據(jù)從進(jìn)程拷貝到緩沖區(qū)或者外設(shè)當(dāng)中。

linux write 怎么查看fd緩沖區(qū),學(xué)好Linux,linux,網(wǎng)絡(luò),運(yùn)維

數(shù)據(jù)可以直接拷貝到緩沖區(qū),高速設(shè)備不用在等待低速設(shè)備,提高計(jì)算機(jī)的效率。

2.刷新策略

緩沖區(qū)的刷新策略:如果有一塊數(shù)據(jù),一次寫入到外設(shè)(效率最高)vs如果有一塊數(shù)據(jù),多次少量寫入到外設(shè),需要多次IO

緩沖區(qū)一定結(jié)合具體的設(shè)備定制自己的刷新策略

1.立即刷新——無緩沖 ,場(chǎng)景較少,比如調(diào)用printf直接fflush

2.行刷新——行緩沖——顯示器 ,數(shù)據(jù)的printf帶上\n就會(huì)立馬顯示到顯示器上。顯示器為什么是行緩沖:顯示器是外設(shè),進(jìn)程運(yùn)行時(shí)在內(nèi)存里的,把數(shù)據(jù)定期要刷新到外設(shè),顯示器設(shè)備比較特殊,是給用戶來看的,從左到右,所以顯示器為了保證刷新效率,并且用戶體驗(yàn)良好,所以顯示器采用行緩沖,滿足用戶的閱讀體驗(yàn)并且在一定程度上效率不至于太低

3.緩沖區(qū)滿——全緩沖——磁盤文件,效率最高,只需要一次IO,比如文件讀寫的時(shí)候,直接寫到磁盤文件

但是存在特殊情況:a.用戶強(qiáng)制刷新 b,進(jìn)程退出——一般到要進(jìn)行緩沖區(qū)刷新

所以對(duì)于全緩沖,緩沖區(qū)滿了采取刷新,減少IO次數(shù),提高效率。

3.在哪里

緩沖區(qū)的位置究竟在哪里:從上面的例子我們直接往顯示器上打印結(jié)果為4條,往文件打印為7條,這跟緩沖區(qū)有關(guān),同時(shí)這也說明了緩沖區(qū)一定不在內(nèi)核中,為什么?如果在內(nèi)核中write也應(yīng)該打印兩次,write是系統(tǒng)接口。我們之前談?wù)摰乃芯彌_區(qū)都指的是用戶級(jí)語言層面提供的緩沖區(qū)。這個(gè)緩沖區(qū),在stdout,stdin,stderr對(duì)應(yīng)的類型---->FILE*,FILE是一個(gè)結(jié)構(gòu)體,里面封裝了fd,同時(shí)還包括了一個(gè)緩沖區(qū)!

FILE結(jié)構(gòu)體緩沖區(qū),所以我們直接要強(qiáng)制刷新的時(shí)候fflush(文件指針),關(guān)閉文件fclose(文件指針),這是因?yàn)閭鬟M(jìn)去的文件指針對(duì)應(yīng)的緩沖區(qū)

從源碼出發(fā),我們可以來看一看FILE結(jié)構(gòu)體:

linux write 怎么查看fd緩沖區(qū),學(xué)好Linux,linux,網(wǎng)絡(luò),運(yùn)維

linux write 怎么查看fd緩沖區(qū),學(xué)好Linux,linux,網(wǎng)絡(luò),運(yùn)維

所以我們一般所說的緩沖區(qū)是語言級(jí)別的緩沖區(qū),C語言提供的在FILE結(jié)構(gòu)體里對(duì)應(yīng)的緩沖區(qū)。

現(xiàn)在,我們現(xiàn)在重新來看一看剛開始的現(xiàn)象:

linux write 怎么查看fd緩沖區(qū),學(xué)好Linux,linux,網(wǎng)絡(luò),運(yùn)維

1.如果我們沒有進(jìn)行重定向>,看到了4條消息,stdout默認(rèn)使用的是行刷新,在進(jìn)程fork之前,三條C函數(shù)已經(jīng)將數(shù)據(jù)打印輸出到顯示器上(外設(shè)),你的FILE內(nèi)部進(jìn)程內(nèi)部就不存在對(duì)應(yīng)的數(shù)據(jù)了。

2.如果我們進(jìn)行了重定向>,寫入文件不在是顯示器,而是普通文件,采用的刷新策略是全緩沖,之前的3條C函數(shù)雖然帶了\n,但是不足以將stdout緩沖區(qū)寫滿,所以數(shù)據(jù)并沒有刷新! 在執(zhí)行fork的時(shí)候,stdout屬于父進(jìn)程,fork創(chuàng)建子進(jìn)程緊接著就是進(jìn)程退出,誰先退出就要進(jìn)行緩沖區(qū)刷新,刷新的本質(zhì)就是修改,修改的時(shí)候發(fā)生寫時(shí)拷貝!所以數(shù)據(jù)最終會(huì)顯示兩份!上面的過程都和write無關(guān),write沒有FILE,而用的是fd,就沒有C提供的緩沖區(qū)!

簡(jiǎn)單總結(jié)來說:重定向?qū)е滤⑿虏呗园l(fā)生了改變(由行緩沖變成了全緩沖)。同時(shí)發(fā)生了寫時(shí)拷貝,父子進(jìn)程各自刷新


三、理解緩沖區(qū)

對(duì)于緩沖區(qū)的理解我們可以自己通過代碼來簡(jiǎn)單實(shí)現(xiàn):

FILE_結(jié)構(gòu)體的設(shè)計(jì),這里為了避免與FILE發(fā)生沖突,我們命名為FILE_:

#define SIZE 1024
typedef struct _FILE
{
    int flags;//刷新方式
    int fileno;//文件描述符
    int cap;//buffer的總?cè)萘?    int size;//buffer當(dāng)前使用量
    char buffer[SIZE];//緩沖區(qū)                                                                              }FILE_;               

主函數(shù):

int main()        
{         
    //打開
    FILE_ *fp = fopen_("./log.txt","w");
    //打開失敗
    if(fp==NULL)                        
    {                                   
        return 1;
    }            
    int cnt = 10;
    const char*masg = "hello world ";
    while(1)                         
    {
        //寫入
        fwrite_(masg,strlen(masg),fp);
        //刷新
        fflush_(fp);
        //睡眠
        sleep(1);                     
        printf("count:%d\n",cnt);
        cnt--;                   
        if(cnt==0) break;        
    }   
    //關(guān)閉
    fclose_(fp);                                                                               
    return 0;                                                                                  
}                                                                                              

對(duì)于C語言來說,文件接口一旦打開成功,其余接口要帶上FILE*,因?yàn)镕ILE結(jié)構(gòu)體里包含了各種數(shù)據(jù):

下面是我們需要自己實(shí)現(xiàn)的文件接口:

//打開
FILE_ * fopen_(const char*path_name,const char*mode);
//以下的接口都需要帶上FILE_*
void  fwrite_(const void *ptr,int num, FILE_*fp);

void fflush_(FILE_*fp);

void fclose_(FILE_* fp);

fopen_:打開我們需要去判斷具體是按什么方式打開:

FILE_ *fopen_(const char *path_name, const char *mode)
{
    int flags = 0;
    int defaultMode=0666; //設(shè)置默認(rèn)權(quán)限
    //讀方式
    if(strcmp(mode, "r") == 0)
    {
        flags |= O_RDONLY;
    }
    //寫方式
    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);
    }
    //其他
    else
    {
        //其他方式這里就不展開了
    }
    int fd = 0;

    if(flags & O_RDONLY) fd = open(path_name, flags);
    else fd = open(path_name, flags, defaultMode);
    //處理打開失敗
    if(fd < 0)
    {
        const char *err = strerror(errno);
        write(2, err, strlen(err));
        return NULL; 
    }
    //打開成功
    FILE_ *fp = (FILE_*)malloc(sizeof(FILE_));
    assert(fp);

    fp->flags = SYNC_LINE; //默認(rèn)設(shè)置成為行刷新
    fp->fileno = fd;
    fp->cap = SIZE;
    fp->size = 0;
    memset(fp->buffer, 0 , SIZE);
    return fp; 
}

fwrite_:

void fwrite_(const void *ptr, int num, FILE_ *fp)
{
    // 寫入到緩沖區(qū)中
    memcpy(fp->buffer+fp->size, ptr, num); //不考慮緩沖區(qū)溢出的問題
    fp->size += num;
    // 判斷是否刷新
    if(fp->flags & SYNC_NOW)
    {
        write(fp->fileno, fp->buffer, fp->size);
        fp->size = 0; //清空緩沖區(qū)
    }
    else if(fp->flags & SYNC_FULL)
    {
        if(fp->size == fp->cap)
        {
            write(fp->fileno, fp->buffer, fp->size);
            fp->size = 0;
        }
    }
    else if(fp->flags & SYNC_LINE)
    {
        if(fp->buffer[fp->size-1] == '\n') // abcd\nefg在這個(gè)地方不考慮
        {
            write(fp->fileno, fp->buffer, fp->size);
            fp->size = 0;
        }
    }
    else{
    }
}

fclose:

void fclose_(FILE_ * fp)
{
    fflush_(fp);
    close(fp->fileno);
}

fflush_:這里將數(shù)據(jù)強(qiáng)制要求操作系統(tǒng)進(jìn)行外設(shè)刷新要用到fsync:文章來源地址http://www.zghlxwxcb.cn/news/detail-819040.html

void fflush_(FILE_ *fp)
{
    if( fp->size > 0) write(fp->fileno, fp->buffer, fp->size);
    fsync(fp->fileno); //將數(shù)據(jù),強(qiáng)制要求OS進(jìn)行外設(shè)刷新!
    fp->size = 0;
}

到了這里,關(guān)于【Linux】理解緩沖區(qū)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

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

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

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

    2024年01月20日
    瀏覽(22)
  • Linux文件系列: 深入理解緩沖區(qū)和C標(biāo)準(zhǔn)庫的簡(jiǎn)單模擬實(shí)現(xiàn)

    Linux文件系列: 深入理解緩沖區(qū)和C標(biāo)準(zhǔn)庫的簡(jiǎn)單模擬實(shí)現(xiàn)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    淺談linux緩沖區(qū)的認(rèn)識(shí)!

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

    2024年02月05日
    瀏覽(20)
  • 【Linux】緩沖區(qū)+磁盤+動(dòng)靜態(tài)庫

    【Linux】緩沖區(qū)+磁盤+動(dòng)靜態(tài)庫

    緩沖區(qū)的本質(zhì)就是一段用作緩存的 內(nèi)存 。 節(jié)省進(jìn)程進(jìn)行數(shù)據(jù)IO的時(shí)間。進(jìn)程使用fwrite等函數(shù)把數(shù)據(jù)拷貝到緩沖區(qū)或者外設(shè)中。 3.1、 立即刷新(無緩沖)——ffush() 情況很少,比如調(diào)用printf后,手動(dòng)調(diào)用fflush刷新緩沖區(qū)。 3.2、 行刷新(行緩沖)——顯示器 顯示器需要滿足人

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

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

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

    2024年02月07日
    瀏覽(25)
  • 【Linux】基礎(chǔ)IO —— 緩沖區(qū)深度剖析

    【Linux】基礎(chǔ)IO —— 緩沖區(qū)深度剖析

    (???(??? )??,我是 Scort 目前狀態(tài):大三非科班啃C++中 ??博客主頁:張小姐的貓~江湖背景 快上車??,握好方向盤跟我有一起打天下嘞! 送給自己的一句雞湯??: ??真正的大師永遠(yuǎn)懷著一顆學(xué)徒的心 作者水平很有限,如果發(fā)現(xiàn)錯(cuò)誤,可在評(píng)論區(qū)指正,感謝?? ????

    2024年02月02日
    瀏覽(18)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包