目录
在阐述golang网络库使用什么网络编程模型之前,需要先简单说一下五种IO模型,先让大家对操作系统I/O有个基本的概念。
----本文章是基于unix下的相关知识,如果unix I/O模型比较熟悉的话,可以直接看第二章和第三章
unix下的五种I/O模型
1.阻塞式I/0
阻塞式I/O是最流行的I/O模型,正常情况下,所有的网络连接都是阻塞的,在数据读写时,会产生阻塞,阻塞分为以下两个阶段:
①第一阶段是数据等待:等待数据从网络中到达网卡,并复制到内核缓冲区;(点我了解网卡的数据包接收过程)
②第二阶段是数据读取:将内核缓存区的数据复制到应用进程的缓冲区。
2.非阻塞式I/O
用户进程在尝试读取I/O数据时(数据写出同理),如果内核缓冲区没有数据,操作系统不会将应用进程置为休眠/阻塞状态,而是直接返回错误给应用进程,告知进程当前没有数据准备好,这个是非阻塞I/O的概念。
如果想正常读取或者写入数据,需要进行多次轮询内核,直到内核缓冲区做好准备。当内核缓冲区数据做好准备时,读取内核缓冲区数据也会产生进行阻塞,效果等同阻塞式I/O第二阶段。
3.I/O复用模型
常见的I/O复用模型有:select、poll、epoll,例如:用户进程使用epoll管理多个网络连接,然后用户进程会阻塞于epoll的系统调用时,等待epoll返回给用户进程哪些网络连接做好了读写准备,最后在从连接中读取或者写入数据。
常见应用场景:当服务程序需要承载大量TCP链接的时候,比如redis数据库、IM通讯、常见web服务等等。
在网络并发编程中,很多语言都会使用I/O复用模型,来实现对多个网络连接的管理,比如我们的golang网络库底层,就使用了epoll模型来管理网络连接。