基本概念
个人在学习linux高性能服务器中容易遇到一些容易混淆的概念。以及一些知识的个人总结。
阻塞和非阻塞
阻塞指的是在调用时没有收到返回结果,当前线程则会挂起。直到调用线程收到返回结果后,当前进程才会继续运行。
非阻塞则指的是调用时没有收到返回结果,当前线程则也会继续运行。
同步和异步
同步指的是调用没有结果时,不会返回结果。知道有结果时才返回。
异步指的是无论有没结果,都直接返回。但是调用的结果由被调用者通过一些方式来通知调用者。
小结
在一开始学习这四个概念的时候真的是一头雾水,不过只要理解了阻塞与非阻塞的重点在于状态,同步和异步的重点在于消息通讯机制。就能很容易理解。
阻塞和非阻塞是调用者没有收到返回结果时,是否挂起的一个状态。
而同步和异步的重点在于这是一种消息通讯机制。同步是由调用者主动等待被调用者。异步则是被调用者主动通知调用者。
服务器编程框架
模块
这里之间使用了《linux高性能服务器编程》第九章中给出的模型,一目了然。
模块 | 单个服务器程序 | 服务器机群 |
---|---|---|
IO处理单元 | 处理连接,读写数据 | 作为接入服务器 |
逻辑单元 | 业务进程或线程 | 逻辑服务器 |
网络存储单元 | 本地数据 | 数据库服务器 |
请求队列 | 各单元之间的通信 | 各服务器之间永久的tcp连接 |
I/O模型
IO模型 | 读写操作和阻塞阶段 |
---|---|
阻塞IO | 程序阻塞读写函数 |
IO复用 | 程序阻塞IO复用系统调用,但可以同时监听多个IO事件,对IO读写是非阻塞的 |
SIGIO信号 | 信号触发读写就绪事件,用户程序执行读写操作,程序没有阻塞阶段 |
异步IO | 内核执行读写操作并触发读写完成事件。程序没有阻塞阶段 |
这里提一下其实应该还有非阻塞IO,但是书上并没写上去。这里补充一下。
IO操作时发生了什么?
具体参考大佬文章unix网络编程时从write到read发生了什么
如果文件描述符并非是一个socket的描述符。而是一个存放在硬盘上的普通文件的文件描述符,那么write则会写入页缓存。所以才会有sync之类的函数,进行同步。
零拷贝
我们知道在用户空间,和内核空间之间切换会消耗大量的资源。而零拷贝则是为了减少资源消耗。
具体可以看Linux中的零拷贝
而linux中零拷贝函数有sendfile,splice,tee。其中sendfile发送对象一定要是一个socket文件描述符。而splice传送参数之一必须为管道。
事件处理模式
Reactor
Reactor是一种事件处理模式,常见于同步IO模型。Reactor模式下主线程只负责监听文件描述符。如果有事件发生,主线程会通知工作线程,工作线程负责其他工作,如建立新连接,读写数据,处理客户端请求等。
Proactor
Proactor常见于异步IO模型,与Reactor不同,Proactor工作线程只负责业务逻辑,其他操作都交给主线程和内核。
并发
并发的目的是为了让程序执行多个任务。但由于计算机IO操作的速度远低于CPU计算速度。使得并发编程能让IO密集型程序CPU利用率显著提升。但对计算密集型的程序提升可能就不大了。