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

Linux學習記錄——?? 高級IO(1)

這篇具有很好參考價值的文章主要介紹了Linux學習記錄——?? 高級IO(1)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


其它IO類型的實現(xiàn)在這篇之后的三篇

1、IO

input,output。調(diào)用read或recv接口時,如果對方長時間不向我方接收緩沖區(qū)拷貝數(shù)據(jù),我們的進程就只能阻塞,這是讀取條件不滿足。阻塞的時間成本最后會體現(xiàn)在用戶上。因此可以說,IO = 等 + 數(shù)據(jù)拷貝。高效IO則是單位事件內(nèi),等的比重越低,IO效率越高。

可以看出IO是有條件的,滿足條件就叫IO時間就緒。

IO有五種模型

2、同、異步IO(5種IO類型)

調(diào)用讀取用的接口后,對于有自己的接收緩沖區(qū),有5種IO方式

阻塞IO:如果緩沖區(qū)內(nèi)沒有好數(shù)據(jù),系統(tǒng)調(diào)用就一直阻塞等待,不做別的事情,直到準備好數(shù)據(jù),才開始讀取并返回。所有的套接字默認都是阻塞IO。

非阻塞IO:單次檢驗緩沖區(qū)內(nèi)沒有數(shù)據(jù),recv函數(shù)就返回EWOULDBLOCK,每隔一段時間再調(diào)用recv接口來查看緩沖區(qū),如果有就讀取并返回數(shù)據(jù),沒有就還返回上面的。這也就是非阻塞輪詢。

阻塞與非阻塞的區(qū)別在于等的方式不同,不過都要自己去拷貝數(shù)據(jù)。非阻塞在沒得到結果前就不阻塞當前進程,直接返回,過一會再來查看;阻塞就是一直阻塞等待,直到讀取數(shù)據(jù)再返回。

上面兩個等的方式不同,但拷貝方式相同。

信號驅(qū)動IO:緩沖區(qū)內(nèi)有數(shù)據(jù)時,就發(fā)送SIGIO信號通知上層調(diào)用接口來讀取。信號是告知上層什么時候可以讀取的,接口是在信號處理了之后才調(diào)用的。

recv函數(shù)調(diào)用后會先檢測有沒有數(shù)據(jù),也就是條件檢測,沒有返回,有才讀取再返回。像這樣的接口只使用一個文件描述符。

多路復用/多路轉接IO:執(zhí)行一個進程,傳多個文件描述符,調(diào)用多個接口來等待數(shù)據(jù),進程只負責等待數(shù)據(jù),等到有了數(shù)據(jù),也就是IO條件就緒,就通知上層調(diào)用recv接口來讀取并返回。

多路復用IO是效率最高的,因為并不只是一個進程在等,而是很多個進程在等,那么等待成功的可能性就更高。單個進程等待的概率和多個進程等待的概率相比。

上面4個都是同步IO。

異步IO:不參與等待過程,只是發(fā)起一個進程,給一個緩沖區(qū)來接收數(shù)據(jù)。至于結果怎么樣,由操作系統(tǒng)來決定。多路復用是進程在等待,異步IO是系統(tǒng)在等待。

兩種IO方式的區(qū)別是有沒有參與等以及讀取的過程。實際上,對應到系統(tǒng),應當是一個進程通過特定的文件描述符,等待IO事件就緒,通過系統(tǒng)調(diào)用來讀取數(shù)據(jù)拷貝到上層。

recv函數(shù)就是在做條件檢測,條件通過再讀取。

3、其它高級IO

記錄鎖、系統(tǒng)V流機制。存儲映射IO(mmap),readv和writev函數(shù)等

4、非阻塞IO

int main()
{
	char buffer[64];
	while(true)
	{
		printf(">>> ");
		fflush(stdout);
		ssize_t n = read(0, buffer, sizeof(buffer) - 1);
		if(n > 0)
		{
			buffer[n - 1] = 0;
			std::cout << "echo# " << buffer << std::endl;
		}
	}
}

這就是一個等待的過程,如果我們不輸入,就一直卡在read那里。這是阻塞,如果要變成非阻塞,用fcntl接口。

#include <fcntl.h>
int fcntl(int fd, int cmd, …/* arg */);

cmd值有5種

復制一個現(xiàn)有的描述符(cmd=F_DUPFD)
獲得/設置文件描述符標記(cmd=F_GETFD或F_SETFD)
獲得/設置文件狀態(tài)標記(cmd=F_GETFL或F_SETFL)//GET獲得文件狀態(tài)標記位,SET設置這個文件新的狀態(tài)
獲得/設置異步I/O所有權(cmd=F_GETOWN或F_SETOWN)
獲得/設置記錄鎖(cmd=F_GETLK,F(xiàn)_SETLK或F_SETLKW)

void SetNonBlock(int fd) {
	int fl = fcntl(fd, F_GETFL);//使用F_GETFL將當前的文件描述符的屬性取出來(這是一個位圖)
	if (fl < 0) {
 		perror("fcntl");
 		return; 
 	}
	fcntl(fd, F_SETFL, fl | O_NONBLOCK);//然后再使用F_SETFL將文件描述符設置回去. 設置回去的同時, 加上一個O_NONBLOCK參數(shù)
}

非阻塞和阻塞都是文件的讀取方式,在文件結構體中就是一個變量設為1或0,這里的O_NONBLOCK是宏,只有一個比特位,通過fcntl將這個數(shù)設置進文件結構體。

#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cstdio>
#include <cstring>

void SetNonBlock(int fd)
{
	int fl = fcntl(fd, F_GETFL);//使用F_GETFL將當前的文件描述符的屬性取出來(這是一個位圖)
	if (fl < 0)
    {
        std::cerr << "error string: " << strerror(errno) << " error code: " << errno << std::endl;
        return ;
    }
	fcntl(fd, F_SETFL, fl | O_NONBLOCK);//然后再使用F_SETFL將文件描述符設置回去. 設置回去的同時, 加上一個O_NONBLOCK參數(shù)
}

int main()
{
	char buffer[64];
    //SetNonBlock(0);//0表示非阻塞
	while(true)
	{
		printf(">>> ");
		fflush(stdout);
		ssize_t n = read(0, buffer, sizeof(buffer) - 1);
		if(n > 0)
		{
			buffer[n - 1] = 0;
			std::cout << "echo# " << buffer << std::endl;
		}
        else if(n == 0)
        {
            std::cout << "end file" << std::endl;
            break;
        } 
        else
        {
            std::cout << "read error??" << std::endl;
            break;
        } 
	}
}

不設置成0,就是阻塞。read那里不是0而是4,當前沒有打開文件描述符為4的文件,就會read error。加上錯誤原因

        else
        {
            std::cerr << "read error?" << "error string: " << strerror(errno) << " error code: " << errno << std::endl;
            break;
        } 

現(xiàn)在再用上SetNonBlock,設置為0,那么即使不輸入,也會出錯,因為它不阻塞,直接去判斷,沒輸入也沒讀取完,所以就打印錯誤語句

Linux學習記錄——?? 高級IO(1),Linux學習,linux,學習

那么這里就在每一次循環(huán)后sleep一會。只有在輸入時才會打印正常語句,不輸入就一直打印錯誤語句。非阻塞IO在底層沒有數(shù)據(jù)時,就以出錯形式返回,不過不算正式地出錯。

區(qū)分一下

        else
        {
            if(errno == EAGAIN || errno == EWOULDBLOCK)//也就是錯誤碼為11的兩個,表示非阻塞式的出錯返回
            {
                //底層數(shù)據(jù)沒有準備好,下次繼續(xù)檢測
                sleep(1);
                std::cout << "data not ready" << std::endl;
                continue;
            }
            else if(errno == EINTR)
            {
                //這次IO被信號中斷,需要重新讀取
                continue;
            }
            std::cerr << "read error? " << "error string: " << strerror(errno) << " error code: " << errno << std::endl;
            break;
        }

非阻塞IO在沒有得到數(shù)據(jù)之前,可以做別的工作,模擬一下:

#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <cstdio>
#include <cstring>
#include <vector>
#include <functional>

void PrintLog()
{
    std::cout << "這個是一個日志例程" << std::endl;
}

void OpenMysql()
{
    std::cout << "這個是一個操作數(shù)據(jù)庫的例程" << std::endl;
}

void CheckNet()
{
    std::cout << "這個是一個檢測網(wǎng)絡狀態(tài)的例程" << std::endl;
}

using func_t = std::function<void (void)>;
std::vector<func_t> funcs;

void LoadTask()
{
    funcs.push_back(PrintLog);
    funcs.push_back(OpenMysql);
    funcs.push_back(CheckNet);
}

void HandlerAllTask()
{
    for(const auto& func: funcs) func();
}

void SetNonBlock(int fd)
{
	int fl = fcntl(fd, F_GETFL);//使用F_GETFL將當前的文件描述符的屬性取出來(這是一個位圖)
	if (fl < 0)
    {
        std::cerr << "error string: " << strerror(errno) << " error code: " << errno << std::endl;
        return ;
    }
	fcntl(fd, F_SETFL, fl | O_NONBLOCK);//然后再使用F_SETFL將文件描述符設置回去. 設置回去的同時, 加上一個O_NONBLOCK參數(shù)
}

int main()
{
	char buffer[64];
    SetNonBlock(0);//0表示非阻塞
    LoadTask();
	while(true)
	{
		printf(">>> ");
		fflush(stdout);
		ssize_t n = read(0, buffer, sizeof(buffer) - 1);
		if(n > 0)
		{
			buffer[n - 1] = 0;
			std::cout << "echo# " << buffer << std::endl;
		}
        else if(n == 0)
        {
            std::cout << "end file" << std::endl;
            break;
        }
        else
        {
            if(errno == EAGAIN || errno == EWOULDBLOCK)//也就是錯誤碼為11的兩個,表示非阻塞式的出錯返回
            {
                //底層數(shù)據(jù)沒有準備好,下次繼續(xù)檢測
                HandlerAllTask();
                sleep(1);
                std::cout << "data not ready" << std::endl;
                continue;
            }
            else if(errno == EINTR)
            {
                //這次IO被信號中斷,需要重新讀取
                continue;
            }
            std::cerr << "read error? " << "error string: " << strerror(errno) << " error code: " << errno << std::endl;
            break;
        }
        sleep(3); 
	}
}

本篇gitee

結束。文章來源地址http://www.zghlxwxcb.cn/news/detail-812646.html

到了這里,關于Linux學習記錄——?? 高級IO(1)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關文章

  • Linux學習記錄——??? 高級IO(6)--- Epoll型服務器(3)(Reactor)

    看完前兩篇再看這篇,本篇將會寫Reactor EpollServer.hpp中創(chuàng)建一個函數(shù)HandlerRequest,用它來做Recver函數(shù)的數(shù)據(jù)處理,也就是數(shù)據(jù)分析。 改一下回調(diào)函數(shù),不向外暴露Connection類。 Main.cc中就不需要兩個函數(shù),一個計算函數(shù)就可以 處理數(shù)據(jù)那里再加上最后的步驟 回到Recver函數(shù),調(diào)用

    2024年01月23日
    瀏覽(31)
  • Linux 學習記錄35(C高級篇)

    Linux 學習記錄35(C高級篇)

    Linux的文件系統(tǒng)結構是一個倒插樹結構,所有的文件都從根目錄出發(fā) 萬物皆文件 1. linux發(fā)行版和內(nèi)核版的區(qū)別 發(fā)行版:內(nèi)核源碼和桌面應用/軟件結合 內(nèi)核版:掌握在linus本人手里,進行維護,內(nèi)核源碼 例: 1. 保證虛擬機有橋接網(wǎng)絡 2. 設置橋接網(wǎng)絡 選擇DHCP或手動填充網(wǎng)絡

    2024年02月09日
    瀏覽(14)
  • Linux 學習記錄37(C高級篇)

    Linux 學習記錄37(C高級篇)

    bash :與終端的交互性較好,一般用于linux使用的都是bash sh :與終端的交互器較差,開發(fā)板的解析器常用的是sh 功能: (1. 輸出 (2. 輸入 將指令運行的結果賦值給變量 shell中只有一維數(shù)組,shell中支持 稀疏數(shù)組 ,shell中支持變長數(shù)組 稀疏數(shù)組:不連續(xù)賦值變量的數(shù)組 shell是弱

    2024年02月11日
    瀏覽(12)
  • 【Linux】高級IO

    【Linux】高級IO

    目錄 IO的基本概念 釣魚五人組 五種IO模型 高級IO重要概念 同步通信 VS?異步通信 阻塞 VS 非阻塞 其他高級IO 阻塞IO 非阻塞IO 什么是IO? I/O(input/output)也就是輸入和輸出,在著名的馮諾依曼體系結構當中,將數(shù)據(jù)從輸入設備拷貝到內(nèi)存就叫做輸入,將數(shù)據(jù)從內(nèi)存拷貝到輸出設

    2024年02月13日
    瀏覽(20)
  • Linux 高級IO

    Linux 高級IO

    小編是雙非本科大二菜鳥不贅述,歡迎米娜桑來指點江山哦 1319365055 ????非科班轉碼社區(qū)誠邀您入駐???? 小伙伴們,滿懷希望,所向披靡,打碼一路向北 一個人的單打獨斗不如一群人的砥礪前行 這是和夢想合伙人組建的社區(qū),誠邀各位有志之士的加入?。?社區(qū)用戶好文

    2024年02月08日
    瀏覽(17)
  • 高級IO(Linux)

    高級IO(Linux)

    什么是IO? 就拿 read 系統(tǒng)調(diào)用來說,從緩沖區(qū)中讀取數(shù)據(jù);首先要保證緩沖區(qū)有數(shù)據(jù),若沒有,操作就會被阻塞,也就是等待資源就緒;若有,將數(shù)據(jù)拷貝完之后直接返回;所以,IO分為兩部分:等待資源就緒+拷貝數(shù)據(jù);其中等待資源就緒在整個IO過程中占比非常大,如何降

    2024年02月08日
    瀏覽(36)
  • Linux - 第25節(jié) - Linux高級IO(三)

    Linux - 第25節(jié) - Linux高級IO(三)

    目錄 1.Reactor模式 1.1.Reactor模式的定義 1.2.Reactor模式的角色構成 1.3.Reactor模式的工作流程 2.epoll?ET服務器(Reactor模式) 2.1.epoll?ET服務器源代碼 2.2.epoll?ET服務器源代碼講解 2.2.1.設計思路 2.2.2.Connection結構 2.2.3.TcpServer類 2.2.4.回調(diào)函數(shù) 2.2.5.套接字相關 2.2.6.Reactor模式和Proactor模式

    2024年02月08日
    瀏覽(13)
  • Linux中的高級IO

    Linux中的高級IO

    1.IO 1.1基本介紹 IO實際上就是 input output 在馮諾依曼體系中就是與外設交互的意思,而我們的網(wǎng)絡通信本質(zhì)上也是一種IO。 1.2基礎io的低效性 為什么基礎io會低效呢?我們以讀取為例來介紹。 當我們底層調(diào)用read函數(shù)的時候,如果緩沖區(qū)沒有數(shù)據(jù) ,我們就會將pcb放入等待隊列,

    2024年02月05日
    瀏覽(14)
  • 【Linux】高級IO --- Reactor網(wǎng)絡IO設計模式

    【Linux】高級IO --- Reactor網(wǎng)絡IO設計模式

    人其實很難抵制誘惑,人只能遠離誘惑,所以千萬不要高看自己的定力。 1. 多路轉接接口select poll epoll所做的工作其實都是事件通知,只向上層通知事件到來,處理就緒事件的工作并不由這些API來完成,這些接口在進行事件通知時,有沒有自己的策略呢? 其實是有的,在網(wǎng)絡

    2024年02月09日
    瀏覽(27)
  • 【Linux】高級IO --- 多路轉接,select,poll,epoll

    【Linux】高級IO --- 多路轉接,select,poll,epoll

    所有通過捷徑所獲取的快樂,無論是金錢、性還是名望,最終都會給自己帶來痛苦 1. 后端服務器最常用的網(wǎng)絡IO設計模式其實就是Reactor,也稱為反應堆模式,Reactor是單進程,單線程的,但他能夠處理多客戶端向服務器發(fā)起的網(wǎng)絡IO請求,正因為他是單執(zhí)行流,所以他的成本就

    2024年02月09日
    瀏覽(25)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領取紅包

二維碼2

領紅包