随笔 - 19,  文章 - 0,  评论 - 4,  阅读 - 491

阻塞模式

  • 发生I/O系统调用如果阻塞,进程会被挂起。
    下面的各种模式都是为了解决阻塞模式带来的CPU消耗等问题

非阻塞模式

  • 发生I/O系统调用如果阻塞,返回 -1errno == EWOULDBLOCK.
    根据 Everything is a fileunix的设计哲学,通过 fcntlfd 操作,设置其为非阻塞模式。

I/O多路复用

  • 具体的实现有( select, epoll, kqueue, etc. )用一个线程对一系列的文件描述符遍历,通过文件操作方法 poll 来获得当前的状态,poll 的实现是由相应的 I/O驱动程序实现的。

    如此就可以获得文件描述符的相应状态了。

epoll 效率高的原因

  • 不需要每次将文件描述符从用户空间复制到内核空间,只需一次。
  • 采用边缘触发模式,每当文件描述符状态发生改变,可以在 O(1) 时间内唤醒相应的回调函数。

水平触发,边缘触发

select 只支持水平触发,epoll 支持水平触发和边缘触发。

水平触发(LT,Level Trigger):当文件描述符就绪时,会触发通知,如果用户程序没有一次性把数据读/写完,下次还会发出可读/可写信号进行通知。

边缘触发(ET,Edge Trigger):仅当描述符从未就绪变为就绪时,通知一次,之后不会再通知。

区别:边缘触发效率更高,减少了事件被重复触发的次数,函数不会返回大量用户程序可能不需要的文件描述符。

  • 但使用边缘触发时一定要使用非阻塞模式,因为处理程序只会被唤醒一次当文件描述符的状态发生改变时,我们需要进行多次读操作来获取完整的数据,如果没有数据时非阻塞模式就会 -1 errno == EWOULDBLOCK ,而阻塞模式就会将线程悬挂。
  • 使用水平触发时如果是非阻塞模式,我们可以循环读数据直到 -1 errno == EWOULDBLOCK ,如果是阻塞模式,就要由 select 等的多路复用来判断文件描述符的状态,以免发生线程悬挂。
  • 材料1
  • 材料2
posted on   嗯嗯好傅  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示