0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

网络IO模型:阻塞与非阻塞

麦辣鸡腿堡 来源:盼盼编程 作者:盼盼编程 2023-10-08 17:16 次阅读

阻塞 IO 模型

Linux ,默认情况下所有的 socket 都是阻塞的,一个典型的读操作流程如图所示。

阻塞和非阻塞的概念描述的是用户线程调用内核 IO 操作的方式:阻塞是指 IO 操作需要彻底完成后才返回到用户空间;而非阻塞是指 IO操作被调用后立即返回给用户一个状态值,不需要等到 IO 操作彻底完成。

当应用进程调用了 recvfrom 这个系统调用后,系统内核就开始了 IO 的第一个阶段 :准备数据。

对于网络 IO 来说,很多时候数据在一开始还没到达时,系统内核就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。

当系统内核一直等到数据准备好了,它就会将数据从系统内核中拷贝到用户内存中,然后系统内核返回结果,用户进程才解除阻塞的状态,重新运行起来。所以,阻塞IO 模型的特点就是 IO 执行的两个阶段都被阻塞了。

大部分的 socke接口都是阻塞型的。所谓阻塞型接口是指系统调用时却不返回调用结果,并让当前线程一直处于阻塞状态,只有当该系统调用获得结果或者超时出错时才返回结果。

实际上,除非特别指定,几乎所有的 IO 接口都阻塞型的。这给网络编程带来了一个很大的问题,如在调用 send的同时,线程处于阻塞状态,则在此期间,线程将无法执行任何运算或响应任何网络请求。

非阻塞 IO 模型

在Linux 下,可以通过设置 socket IO 变为非阻塞状态。当一个非阻塞的 socket执行 read 操作时,流程如图:

图片

当用户进程发出 read 操作时,如果内核中的数据还没有准备好,那么它并不会 block 用户进程,而是立刻返回一个错误。

从用户进程角度讲,它发起 read 操作后,并不需要等待,而是马上就得到了一个结果当用户进程判断结果是一个错误时,它就知道数据还没有准备好,于是它可以再次发送 read 操作。

一旦内核中的数据准备好了,并且又再次收到了用户进程的系统调用,那么它马上就将数据复制到了用户内存中,然后返回正确的返回值。

所以,在非阻塞式 IO 中,用户进程其实需要不断地主动询问 kernel数据是否准备好。非阻塞的接口相比于阻塞型接口的显著差异在于被调用之后立即返回,使用如下的函数可以将某句柄归设为非阻塞状态:fcntl( fd , F_SETFL, O_NONBLOCK);

在非阻塞状态下,recv 接口在被调用后立即返回,返回值代表了不同的含义,如下所述。

recv 返回值大于 0,表示接收数据完毕,返回值即是接收到的字节数。

recv 返回 0,表示连接已经正常断开。

recv 返回 -1 ,且 errno 等于 EAGAIN ,表示 recv 操作还没执行完成。

recv 返回 -1,且 errno 不等于 EAGAIN ,表示 recv 操作遇到系统错误 errno。

可以看到服务器线程可以通过循环调用 recv 接口,可以在单个线程内实现对所有连接的数据接收。但是上述模型绝不被推荐,因为循环调用 recv将大幅度占用 CPU 使用率。

此外,在这个方案 recv 更多的是起到检测“操作是否完成”的作用,实际操作系统提供了更为高效的检测“操作是否完成”作用的接口,例如 select多路复用模式,可以次检测多个连接是存活跃。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • IO
    IO
    +关注

    关注

    0

    文章

    448

    浏览量

    39160
  • 内核
    +关注

    关注

    3

    文章

    1372

    浏览量

    40293
  • Linux
    +关注

    关注

    87

    文章

    11304

    浏览量

    209543
  • 网络
    +关注

    关注

    14

    文章

    7568

    浏览量

    88797
收藏 人收藏

    评论

    相关推荐

    Verilog语言中阻塞阻塞赋值的不同

    来源:《Verilog数字系统设计(夏宇闻)》 阻塞阻塞赋值的语言结构是Verilog 语言中最难理解概念之一。甚至有些很有经验的Verilog 设计工程师也不能完全正确地理解:何时使用
    的头像 发表于 08-17 16:18 6384次阅读

    Verilog阻塞阻塞原理分析

    Verilog阻塞阻塞原理分析在Verilog语言最难弄明白的结构中“阻塞赋值”要算一个。甚至是一些很有经验的工程师也不完全明白“
    发表于 11-23 12:02

    Java阻塞通信研究

    本文针对Java NIO 的特性做出分析与阐述,对网络应用中阻塞通信与阻塞通信、NIO的阻塞
    发表于 08-10 10:15 18次下载

    verilog中阻塞赋值和阻塞赋值

    阻塞阻塞语句作为verilog HDL语言的最大难点之一,一直困扰着FPGA设计者,即使是一个颇富经验的设计工程师,也很容易在这个点上犯下一些不必要的错误。阻塞
    发表于 03-15 10:57 7002次阅读

    深入理解阻塞阻塞赋值

    这是一个很好的学习阻塞阻塞的资料,对于FPGA的学习有很大帮助。
    发表于 04-22 11:00 11次下载

    《Linux设备驱动开发详解》第8章、Linux设备驱动中的阻塞阻塞IO

    《Linux设备驱动开发详解》第8章、Linux设备驱动中的阻塞阻塞IO
    发表于 10-27 11:35 9次下载
    《Linux设备驱动开发详解》第8章、Linux设备驱动中的<b class='flag-5'>阻塞</b>与<b class='flag-5'>非</b><b class='flag-5'>阻塞</b><b class='flag-5'>IO</b>

    深入分析同步阻塞网络IO的内部实现详解

    网络开发模型中,有一种非常易于开发同学使用的方式,那就是同步阻塞网络 IO(在 Java 中习惯叫 BIO)。
    的头像 发表于 04-03 14:10 2030次阅读
    深入分析同步<b class='flag-5'>阻塞</b><b class='flag-5'>网络</b><b class='flag-5'>IO</b>的内部实现详解

    简述阻塞赋值和阻塞赋值的可综合性

    阻塞赋值和阻塞赋值的可综合性 Blocking Assignment阻塞赋值和NonBlocking Assignment
    的头像 发表于 05-12 09:45 2727次阅读
    简述<b class='flag-5'>阻塞</b>赋值和<b class='flag-5'>非</b><b class='flag-5'>阻塞</b>赋值的可综合性

    简述Verilog HDL中阻塞语句和阻塞语句的区别

      在Verilog中有两种类型的赋值语句:阻塞赋值语句(“=”)和阻塞赋值语句(“=”)。正确地使用这两种赋值语句对于Verilog的设计和仿真非常重要。 Verilog语言中讲的阻塞
    的头像 发表于 12-02 18:24 6225次阅读
    简述Verilog HDL中<b class='flag-5'>阻塞</b>语句和<b class='flag-5'>非</b><b class='flag-5'>阻塞</b>语句的区别

    时序逻辑中的阻塞阻塞

    Verilog HDL的赋值语句分为阻塞赋值和阻塞赋值两种。阻塞赋值是指在当前赋值完成前阻塞其他类型的赋值任务,
    的头像 发表于 03-15 13:53 3061次阅读

    阻塞阻塞通信的区别 阻塞阻塞应用场景

    阻塞通信(Blocking Communication):当进行阻塞通信时,调用者在发起一个I/O操作后会被阻塞,直到该操作完成返回才能继续执行后续代码。
    的头像 发表于 06-15 17:32 6092次阅读

    阻塞赋值与阻塞赋值

    ”=“阻塞赋值与”
    的头像 发表于 09-12 09:06 1045次阅读
    <b class='flag-5'>阻塞</b>赋值与<b class='flag-5'>非</b><b class='flag-5'>阻塞</b>赋值

    什么是阻塞阻塞

    什么是阻塞阻塞?我们就用管道的读写来举例子。
    的头像 发表于 03-25 10:04 506次阅读

    socket阻塞阻塞的区别是什么

    在计算机编程中,socket 是一种通信端点,用于在网络中进行数据传输。Socket 可以是阻塞的或阻塞的,这两种模式在处理数据传输时有不同的行为。
    的头像 发表于 08-16 11:13 681次阅读

    socket编程中的阻塞阻塞

    网络编程中, socket 是一个非常重要的概念,它提供了一个抽象层,使得开发者可以不必关心底层的网络通信细节。 socket 编程中的阻塞
    的头像 发表于 11-01 16:13 212次阅读