0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

網(wǎng)絡(luò)IO模型:阻塞與非阻塞

麥辣雞腿堡 ? 來源:盼盼編程 ? 作者:盼盼編程 ? 2023-10-08 17:16 ? 次閱讀

阻塞 IO 模型

Linux ,默認(rèn)情況下所有的 socket 都是阻塞的,一個典型的讀操作流程如圖所示。

阻塞和非阻塞的概念描述的是用戶線程調(diào)用內(nèi)核 IO 操作的方式:阻塞是指 IO 操作需要徹底完成后才返回到用戶空間;而非阻塞是指 IO操作被調(diào)用后立即返回給用戶一個狀態(tài)值,不需要等到 IO 操作徹底完成。

當(dāng)應(yīng)用進(jìn)程調(diào)用了 recvfrom 這個系統(tǒng)調(diào)用后,系統(tǒng)內(nèi)核就開始了 IO 的第一個階段 :準(zhǔn)備數(shù)據(jù)。

對于網(wǎng)絡(luò) IO 來說,很多時候數(shù)據(jù)在一開始還沒到達(dá)時,系統(tǒng)內(nèi)核就要等待足夠的數(shù)據(jù)到來。而在用戶進(jìn)程這邊,整個進(jìn)程會被阻塞。

當(dāng)系統(tǒng)內(nèi)核一直等到數(shù)據(jù)準(zhǔn)備好了,它就會將數(shù)據(jù)從系統(tǒng)內(nèi)核中拷貝到用戶內(nèi)存中,然后系統(tǒng)內(nèi)核返回結(jié)果,用戶進(jìn)程才解除阻塞的狀態(tài),重新運(yùn)行起來。所以,阻塞IO 模型的特點(diǎn)就是 IO 執(zhí)行的兩個階段都被阻塞了。

大部分的 socke接口都是阻塞型的。所謂阻塞型接口是指系統(tǒng)調(diào)用時卻不返回調(diào)用結(jié)果,并讓當(dāng)前線程一直處于阻塞狀態(tài),只有當(dāng)該系統(tǒng)調(diào)用獲得結(jié)果或者超時出錯時才返回結(jié)果。

實(shí)際上,除非特別指定,幾乎所有的 IO 接口都阻塞型的。這給網(wǎng)絡(luò)編程帶來了一個很大的問題,如在調(diào)用 send的同時,線程處于阻塞狀態(tài),則在此期間,線程將無法執(zhí)行任何運(yùn)算或響應(yīng)任何網(wǎng)絡(luò)請求。

非阻塞 IO 模型

在Linux 下,可以通過設(shè)置 socket IO 變?yōu)榉亲枞麪顟B(tài)。當(dāng)一個非阻塞的 socket執(zhí)行 read 操作時,流程如圖:

圖片

當(dāng)用戶進(jìn)程發(fā)出 read 操作時,如果內(nèi)核中的數(shù)據(jù)還沒有準(zhǔn)備好,那么它并不會 block 用戶進(jìn)程,而是立刻返回一個錯誤。

從用戶進(jìn)程角度講,它發(fā)起 read 操作后,并不需要等待,而是馬上就得到了一個結(jié)果當(dāng)用戶進(jìn)程判斷結(jié)果是一個錯誤時,它就知道數(shù)據(jù)還沒有準(zhǔn)備好,于是它可以再次發(fā)送 read 操作。

一旦內(nèi)核中的數(shù)據(jù)準(zhǔn)備好了,并且又再次收到了用戶進(jìn)程的系統(tǒng)調(diào)用,那么它馬上就將數(shù)據(jù)復(fù)制到了用戶內(nèi)存中,然后返回正確的返回值。

所以,在非阻塞式 IO 中,用戶進(jìn)程其實(shí)需要不斷地主動詢問 kernel數(shù)據(jù)是否準(zhǔn)備好。非阻塞的接口相比于阻塞型接口的顯著差異在于被調(diào)用之后立即返回,使用如下的函數(shù)可以將某句柄歸設(shè)為非阻塞狀態(tài):fcntl( fd , F_SETFL, O_NONBLOCK);

在非阻塞狀態(tài)下,recv 接口在被調(diào)用后立即返回,返回值代表了不同的含義,如下所述。

recv 返回值大于 0,表示接收數(shù)據(jù)完畢,返回值即是接收到的字節(jié)數(shù)。

recv 返回 0,表示連接已經(jīng)正常斷開。

recv 返回 -1 ,且 errno 等于 EAGAIN ,表示 recv 操作還沒執(zhí)行完成。

recv 返回 -1,且 errno 不等于 EAGAIN ,表示 recv 操作遇到系統(tǒng)錯誤 errno。

可以看到服務(wù)器線程可以通過循環(huán)調(diào)用 recv 接口,可以在單個線程內(nèi)實(shí)現(xiàn)對所有連接的數(shù)據(jù)接收。但是上述模型絕不被推薦,因?yàn)檠h(huán)調(diào)用 recv將大幅度占用 CPU 使用率。

此外,在這個方案 recv 更多的是起到檢測“操作是否完成”的作用,實(shí)際操作系統(tǒng)提供了更為高效的檢測“操作是否完成”作用的接口,例如 select多路復(fù)用模式,可以次檢測多個連接是存活躍。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • IO
    IO
    +關(guān)注

    關(guān)注

    0

    文章

    434

    瀏覽量

    39049
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1360

    瀏覽量

    40185
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11207

    瀏覽量

    208717
  • 網(wǎng)絡(luò)
    +關(guān)注

    關(guān)注

    14

    文章

    7485

    瀏覽量

    88541
收藏 人收藏

    評論

    相關(guān)推薦

    Verilog語言中阻塞阻塞賦值的不同

    來源:《Verilog數(shù)字系統(tǒng)設(shè)計(夏宇聞)》 阻塞阻塞賦值的語言結(jié)構(gòu)是Verilog 語言中最難理解概念之一。甚至有些很有經(jīng)驗(yàn)的Verilog 設(shè)計工程師也不能完全正確地理解:何時使用
    的頭像 發(fā)表于 08-17 16:18 ?6325次閱讀

    Verilog阻塞阻塞原理分析

    Verilog阻塞阻塞原理分析在Verilog語言最難弄明白的結(jié)構(gòu)中“阻塞賦值”要算一個。甚至是一些很有經(jīng)驗(yàn)的工程師也不完全明白“
    發(fā)表于 11-23 12:02

    Java阻塞通信研究

    本文針對Java NIO 的特性做出分析與闡述,對網(wǎng)絡(luò)應(yīng)用中阻塞通信與阻塞通信、NIO的阻塞
    發(fā)表于 08-10 10:15 ?18次下載

    verilog中阻塞賦值和阻塞賦值

    阻塞阻塞語句作為verilog HDL語言的最大難點(diǎn)之一,一直困擾著FPGA設(shè)計者,即使是一個頗富經(jīng)驗(yàn)的設(shè)計工程師,也很容易在這個點(diǎn)上犯下一些不必要的錯誤。阻塞
    發(fā)表于 03-15 10:57 ?6986次閱讀

    深入理解阻塞阻塞賦值

    這是一個很好的學(xué)習(xí)阻塞阻塞的資料,對于FPGA的學(xué)習(xí)有很大幫助。
    發(fā)表于 04-22 11:00 ?11次下載

    《Linux設(shè)備驅(qū)動開發(fā)詳解》第8章、Linux設(shè)備驅(qū)動中的阻塞阻塞IO

    《Linux設(shè)備驅(qū)動開發(fā)詳解》第8章、Linux設(shè)備驅(qū)動中的阻塞阻塞IO
    發(fā)表于 10-27 11:35 ?9次下載
    《Linux設(shè)備驅(qū)動開發(fā)詳解》第8章、Linux設(shè)備驅(qū)動中的<b class='flag-5'>阻塞</b>與<b class='flag-5'>非</b><b class='flag-5'>阻塞</b><b class='flag-5'>IO</b>

    深入分析同步阻塞網(wǎng)絡(luò)IO的內(nèi)部實(shí)現(xiàn)詳解

    網(wǎng)絡(luò)開發(fā)模型中,有一種非常易于開發(fā)同學(xué)使用的方式,那就是同步阻塞網(wǎng)絡(luò) IO(在 Java 中習(xí)慣叫 BIO)。
    的頭像 發(fā)表于 04-03 14:10 ?1989次閱讀
    深入分析同步<b class='flag-5'>阻塞</b><b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>IO</b>的內(nèi)部實(shí)現(xiàn)詳解

    簡述阻塞賦值和阻塞賦值的可綜合性

    阻塞賦值和阻塞賦值的可綜合性 Blocking Assignment阻塞賦值和NonBlocking Assignment
    的頭像 發(fā)表于 05-12 09:45 ?2680次閱讀
    簡述<b class='flag-5'>阻塞</b>賦值和<b class='flag-5'>非</b><b class='flag-5'>阻塞</b>賦值的可綜合性

    簡述Verilog HDL中阻塞語句和阻塞語句的區(qū)別

    ? 在Verilog中有兩種類型的賦值語句:阻塞賦值語句(“=”)和阻塞賦值語句(“=”)。正確地使用這兩種賦值語句對于Verilog的設(shè)計和仿真非常重要。 Verilog語言中講的阻塞
    的頭像 發(fā)表于 12-02 18:24 ?5965次閱讀
    簡述Verilog HDL中<b class='flag-5'>阻塞</b>語句和<b class='flag-5'>非</b><b class='flag-5'>阻塞</b>語句的區(qū)別

    時序邏輯中的阻塞阻塞

    Verilog HDL的賦值語句分為阻塞賦值和阻塞賦值兩種。阻塞賦值是指在當(dāng)前賦值完成前阻塞其他類型的賦值任務(wù),
    的頭像 發(fā)表于 03-15 13:53 ?2954次閱讀

    阻塞阻塞通信的區(qū)別 阻塞阻塞應(yīng)用場景

    阻塞通信(Blocking Communication):當(dāng)進(jìn)行阻塞通信時,調(diào)用者在發(fā)起一個I/O操作后會被阻塞,直到該操作完成返回才能繼續(xù)執(zhí)行后續(xù)代碼。
    的頭像 發(fā)表于 06-15 17:32 ?5869次閱讀

    阻塞賦值與阻塞賦值

    ”=“阻塞賦值與”
    的頭像 發(fā)表于 09-12 09:06 ?968次閱讀
    <b class='flag-5'>阻塞</b>賦值與<b class='flag-5'>非</b><b class='flag-5'>阻塞</b>賦值

    什么是阻塞阻塞?

    什么是阻塞阻塞?我們就用管道的讀寫來舉例子。
    的頭像 發(fā)表于 03-25 10:04 ?448次閱讀

    socket阻塞阻塞的區(qū)別是什么

    在計算機(jī)編程中,socket 是一種通信端點(diǎn),用于在網(wǎng)絡(luò)中進(jìn)行數(shù)據(jù)傳輸。Socket 可以是阻塞的或阻塞的,這兩種模式在處理數(shù)據(jù)傳輸時有不同的行為。
    的頭像 發(fā)表于 08-16 11:13 ?534次閱讀

    socket編程中的阻塞阻塞

    網(wǎng)絡(luò)編程中, socket 是一個非常重要的概念,它提供了一個抽象層,使得開發(fā)者可以不必關(guān)心底層的網(wǎng)絡(luò)通信細(xì)節(jié)。 socket 編程中的阻塞
    的頭像 發(fā)表于 11-01 16:13 ?101次閱讀