四种网络模型:
- 阻塞IO模型
- 非阻塞IO模型
- 多路IO复用模型(select/poll/epoll)
- 异步IO模型(POSIX的aio_系列函数)
网络IO模型.jpg
阻塞/非阻塞:
在Linux中,默认情况下所有socket都是阻塞的。
阻塞和非阻塞的概念描述时候用户线程调用内核IO操作的方式:
- 阻塞是指IO操作需要彻底完成后才返回到用户空间
- 非阻塞是指IO操作被调用后立即返回给用户一个状态值,不需要等到IO操作彻底完成
同步/异步:
同步IO是指进程需要主动检查IO操作的状态,而异步IO是指内核做完后发信号通知给用户态。访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;异步只需要I/O操作完成的通知,并不主动读写数据,由操作系统内核完成数据的读写。
信号驱动IO模型
IO模型除了四种网络IO模型,还有一种信号驱动IO模型。信号驱动IO不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO的信号),然后应用用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过SIGIO信号通知应用进程,数据准备好后的可读状态。应用用户进程收到信号之后,立即调用recvfrom,去读取数据。
对比异步IO模型和信号驱动IO模型
信号驱动IO模型
异步IO模型.png
可以通过上面流程图可以看到区别,信号驱动IO模型的recvfrom接口,还需要等待数据从内核态复制到用户态,而异步调用则不用等待。
IO模型汇总:
image.png
其他:
epoll的socket可以设置为非阻塞的吗?
可以,一般epoll的ET模式可以设置为非阻塞。
一个socket是否设置为阻塞模式,只会影响到connect/accept/send/recv等四个socket API函数,不会影响到select/poll/epoll_wait函数,后三个函数的超时或者阻塞时间是由其函数自身参数控制的。
引用
《UNIX网络编程:卷一》