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

【Linux】語言層面緩沖區(qū)的刷新問題以及簡易模擬實現(xiàn)

這篇具有很好參考價值的文章主要介紹了【Linux】語言層面緩沖區(qū)的刷新問題以及簡易模擬實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


前言

我們接下來要談?wù)摰氖俏覀冋Z言層面的緩沖區(qū)(C,C++之類的),不是我們操作系統(tǒng)內(nèi)核里面自帶的緩沖區(qū),我們每次在打開一個文件的時候,以C語言為例子,C語言會為我們所打開的這個文件分配一塊緩沖區(qū),用來緩存我們讀寫的數(shù)據(jù)`,這個緩沖區(qū)會被放在我們創(chuàng)建的FILE的結(jié)構(gòu)體里面,里面存放著緩沖區(qū)的字段和維護信息

一、緩沖區(qū)刷新方法分類

a.無緩沖–直接刷新

b.行緩沖–不刷新,直到碰到\n才刷新

顯示器寫入一般采用的是行緩沖

c.全緩沖–緩沖區(qū)滿了才刷新

文件寫入一般采用的是全緩沖,緩沖區(qū)滿了或者程序結(jié)束的時候刷新

二、 緩沖區(qū)的常見刷新問題

1.問題

【Linux】語言層面緩沖區(qū)的刷新問題以及簡易模擬實現(xiàn),linux,服務(wù)器,java
我們將可執(zhí)行文件內(nèi)容重定向到log1里面
【Linux】語言層面緩沖區(qū)的刷新問題以及簡易模擬實現(xiàn),linux,服務(wù)器,java
最后我們發(fā)現(xiàn)與C有關(guān)的接口被打印了兩次,這是什么原因呢?

之前我們說過,我們朝文件里面寫入是全緩沖,也就是等緩沖區(qū)滿了或者程序結(jié)束的時候去刷新,打印兩次的都是屬于C語言的接口, 其會建立一個語言層面的緩沖區(qū), 我們在fork之前,printf,fprintf,fwrite寫入的數(shù)據(jù)都存放在語言層面的緩沖區(qū),fork之后創(chuàng)建子進程,子進程對父進程的數(shù)據(jù)內(nèi)容進行拷貝,因為此時緩沖區(qū)為刷新,子進程會連同父進程語言層面緩沖區(qū)內(nèi)容一起拷貝
所以之后,父子進程語言層面的緩沖區(qū)中都存放著相同的數(shù)據(jù),在程序結(jié)束的時候會對語言層面的緩沖區(qū)進行刷新,將其刷新到系統(tǒng)里面的緩沖區(qū),

若子進程先刷新,因為對父進程數(shù)據(jù)進行更改了(即清空語言緩沖區(qū)),這個時候會發(fā)生寫實拷貝,之后子進程緩沖區(qū)的數(shù)據(jù)就被刷新到系統(tǒng)緩沖區(qū)了。
父進程同理,也會進行一遍緩沖區(qū)的刷新,父子進程都對數(shù)據(jù)進行了刷新寫入系統(tǒng)緩沖區(qū),所以文件里面就會寫入兩次。

wirite屬于系統(tǒng)接口,調(diào)用以后會直接寫入到內(nèi)核緩沖區(qū)里面,之后寫入硬盤文件中,沒有語言層面緩沖區(qū)概念,所以只寫入文件一次

2.刷新本質(zhì)

用戶刷新的本質(zhì)是通關(guān)重定向到文件描述符為1的文件(stdout)+write寫入內(nèi)核緩沖區(qū),F(xiàn)ILE對象屬于用戶不是操作系統(tǒng),F(xiàn)ILE里面的緩沖區(qū)屬于語言層面的緩沖區(qū)(用戶級緩沖區(qū)),目前我們認為,只要數(shù)據(jù)刷新到了內(nèi)核中,數(shù)據(jù)就可以寫入硬件了

【Linux】語言層面緩沖區(qū)的刷新問題以及簡易模擬實現(xiàn),linux,服務(wù)器,java
這些C接口最后寫入內(nèi)核緩沖區(qū),本質(zhì)都是調(diào)用write的系統(tǒng)接口文章來源地址http://www.zghlxwxcb.cn/news/detail-752439.html

三、模擬實現(xiàn)

1.Mystdio.h

#include <string.h>

#define SIZE 1024

#define FLUSH_NOW 1//無緩沖
#define FLUSH_LINE 2//行緩沖
#define FLUSH_ALL 4//全緩沖

typedef struct IO_FILE{
    int fileno;//文件描述符
    int flag; //刷新方式
    
    char outbuffer[SIZE]; // 簡單模擬語言層緩沖區(qū)
    int out_pos;//緩沖區(qū)當前大小
}_FILE;

_FILE * _fopen(const char*filename, const char *flag);
int _fwrite(_FILE *fp, const char *s, int len);
void _fclose(_FILE *fp);



2.Mystdio.c

#include "Mystdio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>

#define FILE_MODE 0666//文件默認權(quán)限

 
_FILE * _fopen(const char*filename, const char *flag)
{
    assert(filename);
    assert(flag);

    int f = 0;//文件的寫入方式
    int fd = -1;//文件描述符
    if(strcmp(flag, "w") == 0) {
        f = (O_CREAT|O_WRONLY|O_TRUNC);
        fd = open(filename, f, FILE_MODE);
        //獲取文件描述符
    }
    else if(strcmp(flag, "a") == 0) {
        f = (O_CREAT|O_WRONLY|O_APPEND);
        fd = open(filename, f, FILE_MODE);
    }
    else if(strcmp(flag, "r") == 0) {
        f = O_RDONLY;
        fd = open(filename, f);
    }
    else 
        return NULL;

    if(fd == -1) return NULL;

    _FILE *fp = (_FILE*)malloc(sizeof(_FILE));
    //創(chuàng)建文件指針結(jié)構(gòu)體
    if(fp == NULL) return NULL;

    fp->fileno = fd;
    //fp->flag = FLUSH_LINE;
    fp->flag = FLUSH_ALL;
    fp->out_pos = 0;

    return fp;
}

 
int _fwrite(_FILE *fp, const char *s, int len)
{
    // "abcd\n"
    memcpy(&fp->outbuffer[fp->out_pos], s, len); // 沒有做異常處理, 也不考慮局部問題
    fp->out_pos += len;

    if(fp->flag&FLUSH_NOW)//無緩沖
    {
        write(fp->fileno, fp->outbuffer, fp->out_pos);
        fp->out_pos = 0;
    }
    else if(fp->flag&FLUSH_LINE)//行緩沖
    {
        if(fp->outbuffer[fp->out_pos-1] == '\n'){ // 不考慮其他情況
            write(fp->fileno, fp->outbuffer, fp->out_pos);
            fp->out_pos = 0;
        }
    }
    else if(fp->flag & FLUSH_ALL)//全緩沖
    {
        if(fp->out_pos == SIZE){
            write(fp->fileno, fp->outbuffer, fp->out_pos);
            fp->out_pos = 0;
        }
    }

    return len;
}

void _fflush(_FILE *fp)//手動刷新緩沖區(qū)
{
    if(fp->out_pos > 0){
        write(fp->fileno, fp->outbuffer, fp->out_pos);
        fp->out_pos = 0;
    }
}

void _fclose(_FILE *fp)
{
    if(fp == NULL) return;
    _fflush(fp);
    close(fp->fileno);
    free(fp);
}

3.main.c

#include "Mystdio.h"
#include <unistd.h>

#define myfile "test.txt"

int main()
{
    _FILE *fp = _fopen(myfile, "a");
    if(fp == NULL) return 1;

    const char *msg = "hello world\n";
    int cnt = 10;
    while(cnt){
        _fwrite(fp, msg, strlen(msg));
        // fflush(fp);
        sleep(1);
        cnt--;
    }

    _fclose(fp);

    return 0;
}

到了這里,關(guān)于【Linux】語言層面緩沖區(qū)的刷新問題以及簡易模擬實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【LeetCode】模擬實現(xiàn)FILE以及認識緩沖區(qū)

    【LeetCode】模擬實現(xiàn)FILE以及認識緩沖區(qū)

    刷新緩沖邏輯圖 自定義實現(xiàn) 如何強制刷新內(nèi)核緩沖區(qū) 根據(jù)文件描述符進行強制刷新 例子 像我們進行scanf輸入的時候,其實本身我們輸入的是一串字符串,將這個字符串讀入對應(yīng)的緩沖區(qū)buff后,然后通過分解工作,進一步傳入系統(tǒng),系統(tǒng),系統(tǒng)在通過一些指令輸入輸出想要

    2024年02月11日
    瀏覽(30)
  • STM32使用1.69寸液晶顯示模塊使用緩沖區(qū)實現(xiàn)快速刷新全屏顯示字符串功能

    一個1.69寸SPI接口的液晶顯示模塊,有320*240=76800個點,每個點有2個字節(jié)表示RGB的顏色,所以需要153.6K個字節(jié)的數(shù)據(jù)來刷新全屏,如果SPI口輸出數(shù)據(jù)不是高速并且不緊密排列的話,刷新就會比較慢,有從下到下的肉眼可見的刷新過程,現(xiàn)就是希望使用數(shù)據(jù)緩沖區(qū)(我理解這就是

    2024年01月20日
    瀏覽(21)
  • 【Linux】文件緩沖區(qū)

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

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

    2024年02月10日
    瀏覽(25)
  • 【Linux】理解緩沖區(qū)

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

    我們發(fā)現(xiàn) printf 和 fwrite (庫函數(shù))都輸出了2次,而 write 只輸出了一次(系統(tǒng)調(diào)用)。為什么呢?肯定和fork有關(guān)! C接口的函數(shù)被打印了兩次系統(tǒng)接口前后只是打印了一次:和fork函數(shù)有關(guān),fork會創(chuàng)建子進程。在創(chuàng)建子進程的時候,數(shù)據(jù)會被處理成兩份,父子進程發(fā)生寫時拷

    2024年01月23日
    瀏覽(20)
  • 【linux】重定向+緩沖區(qū)

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

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

    2024年02月08日
    瀏覽(22)
  • 【Linux】深入理解緩沖區(qū)

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

    目錄 什么是緩沖區(qū) 為什么要有緩沖區(qū) 緩沖區(qū)刷新策略 緩沖區(qū)在哪里 ?手動設(shè)計一個用戶層緩沖區(qū) 緩沖區(qū)本質(zhì)上一塊內(nèi)存區(qū)域,用來保存臨時數(shù)據(jù)。 緩沖區(qū)在各種計算任務(wù)中都廣泛應(yīng)用,包括輸入/輸出操作、網(wǎng)絡(luò)通信、圖像處理、音頻處理等。 這塊內(nèi)存區(qū)域是由 誰提供的

    2024年02月15日
    瀏覽(22)
  • Linux之緩沖區(qū)的理解

    Linux之緩沖區(qū)的理解

    目錄 一、問題引入 二、緩沖區(qū) 1、什么是緩沖區(qū) 2、刷新策略 3、緩沖區(qū)由誰提供 4、重看問題 三、緩沖區(qū)的簡單實現(xiàn) 我們先來看看下面的代碼:我們使用了C語言接口和系統(tǒng)調(diào)用接口來進行文件操作。在代碼的最后,我們還使用fork函數(shù)創(chuàng)建了一個子進程。 ?代碼運行結(jié)果如

    2024年02月03日
    瀏覽(24)
  • 【Linux】深入理解文件緩沖區(qū)

    【Linux】深入理解文件緩沖區(qū)

    問題引入 首先看一段代碼: 運行代碼,結(jié)果如下: 如果此時將輸出結(jié)果重定向一下: 會發(fā)現(xiàn) printf 、 fwrite 都打印了兩次。 究其原因,就要談到緩沖區(qū)和緩沖區(qū)刷新策略的概念了。 如何理解緩沖區(qū) 假設(shè)你在青島,你要從網(wǎng)上買一件商品,商家所在地是北京。你不會跑去北

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

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

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

    2024年02月05日
    瀏覽(20)
  • linuxC語言緩沖區(qū)及小程序的實現(xiàn)

    linuxC語言緩沖區(qū)及小程序的實現(xiàn)

    為緩和 CPU 與 I/O 設(shè)備之間速度不匹配,文件緩沖區(qū)用以暫時存放讀寫期間的文件數(shù)據(jù)而在內(nèi)存區(qū)預(yù)留的一定空間。使用文件緩沖區(qū)可減少讀取硬盤的次數(shù)。 系統(tǒng)自動地在內(nèi)存為程序中每一個正在使用的文件開辟一塊文件緩沖區(qū)。 從內(nèi)存向磁盤輸出數(shù)據(jù),先送到內(nèi)存中的緩沖

    2024年02月04日
    瀏覽(28)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包