站在巨人肩上说I/O模型和I/O多路复用(1)

本文介绍了从单线程到Reactor模型的网络通信发展历程,强调理解I/O模型和I/O多路复用在高性能网络通信中的重要性。文章深入浅出地讲解了Linux中的用户空间和内核空间,以及如何通过系统接口在两者间切换,以进行文件操作等系统调用。并提到通过top命令观察CPU时间片在用户空间和内核空间的分配情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近阅读某大牛的公众号时,其讲Kafka请求全流程和源码时又提到了熟悉又陌生的Reactor模式。熟悉是因为可以说基本上只要底层是高性能网络通信就一定和Reactor模式息息相关,比如Netty,Redis等底层都是Reactor模式。陌生是仍不能探其究竟、知其本真。

早期的网络编程当一个请求过来了,要么当前线程直接就处理了要么另起一个新的线程去处理,一个线程很容易处理不过来且又没有充分利用计算机资源,而每次新起一个线程则对计算机资源要求太高。没错,线程池是一个很好的选择,池化技术确实能缓解资源问题。但池子也是有限的,池子里的线程也是在候着连接等待指示。现在的互联网早就突破C10K(concurrent 10000 connection),应对C10K问题的关键在于充分利用计算机资源、减少CPU消耗。故,引入I/O多路复用,由一个线程监控一堆连接,同步等待一个或多个I/O事件的到来,分配给对应的handler处理,即Reactor模式。

网络通信模型的发展线路:
单线程 => 多线程 => 线程池 => Reactor模型

讲那么多,就是想说理解I/O模型和I/O多路复用很重要。呵呵。

C10K问题本质上是操作系统的问题,故还得从操作系统入手。
本节先理解操作系统(linux)的User space用户空间和Kernel space内核空间。
简单来说,Kenel space是linux的内核运行空间,User space是用户程序的运行空间。安全起见,它们是相互隔离的,当用户程序崩溃时内核不受影响。在内核空间可以执行任何命令、调用系统的一切资源;用户空间内只能执行简单的运算,不能直接调用系统资源,须通过系统接口才能向内核发出指令。通过系统接口,进程可以从用户空间切换到内核空间。
举例:

str = "something nice weights light" // 用户空间
x = x + 1
file.write(str) // 切换到内核空间
y = x + 100 // 切换回用户空间

上面代码,第一行、第二行都是简单的赋值运算直接用户空间执行,第三行用户不能直接写文件须切换到内核空间通过内核安排,第四行又是赋值运算则切换回用户空间。
在linux系统中可通过top命令查看CPU时间片在用户空间和内核空间的分配情况:
在这里插入图片描述
上图红色框中的各指标就是CPU的时间分配统计,其中us(user)即CPU消耗在User space的时间占比,sy(system)即CPU消耗在Kernel space的时间占比,其他6个指标含义:
ni:niceness 的缩写,CPU 消耗在 nice 进程(低优先级)的时间百分比
id:idle 的缩写,CPU 消耗在闲置进程的时间百分比,这个值越低,表示 CPU 越忙
wa:wait 的缩写,CPU 等待外部 I/O 的时间百分比,这段时间 CPU 不能干其他事,但是也没有执行运算,这个
值太高就说明外部设备有问题
hi:hardware interrupt 的缩写,CPU 响应硬件中断请求的时间百分比
si:software interrupt 的缩写,CPU 响应软件中断请求的时间百分比
st:stole time 的缩写,该项指标只对虚拟机有效,表示分配给当前虚拟机的 CPU 时间之中,被同一台物理机上
的其他虚拟机偷走的时间百分比。

To Be Continued…

大表哥的剑
2020.8.29

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值