常见的IO模型:
同步阻塞、同步非阻塞、IO多路复用(Reactor设计模式,也叫异步阻塞IO)、异步IO(Proactor设计模式)
异步和同步的区别:是描述用户线程和内核的交互方式。
同步:用户线程发起IO请求后需要等待或轮询内核IO操作完成后才能继续执行;
异步:用户线程发起IO请求后仍可继续执行,当内核操作IO完成后会通知用户线程,或调用用户线程注册的回调函数;
阻塞和非阻塞的区别:是描述用户线程调用内核IO的操作方式。
阻塞:IO操作需要彻底完成后才能返回用户空间;
非阻塞:IO操作被调用后立即返回给用户一个状态值,无需等IO操作完成;
IO同步阻塞,看附件;
用户线程使用同步阻塞IO的伪代码:
{
read(socket, buffer);
process(buffer);
}
即用户线程需要等待read将socket中的数据读取到buffer后,才继续处理接收的数据。整个IO请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够。
IO同步非阻塞,看附件:
用户线程使用同步非阻塞IO的伪代码:
{
while(read(socket, buffer) != SUCCESS)
;
process(buffer);
}
用户线程需要不断地调用read,尝试读取socket中的数据,直到读取成功后,才继续处理接收的数据。整个IO请求的过程中,虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断地轮询、重复请求,消耗了大量的CPU的资源。一般很少直接使用这种模型。
IO多路复用模型,看附件:
IO多路复用模型是建立在内核提供的多路分离函数select基础之上的,使用select函数可以避免同步非阻塞IO模型中轮询等待的问题。
用户线程首先将需要进行IO操作的socket添加到select中,然后阻塞等待select系统调用返回。当数据到达时,socket被激活,select函数返回。用户线程正式发起read请求,读取数据并继续执行。表面看,使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还多了添加监视socket,以及调用select函数的额外操作,效率更差。但是,使用select以后最大的优势是用户可以在一个线程内同时处理多个socket的IO请求。用户可以注册多个socket,然后不断地调用select读取被激活的socket,即可达到在同一个线程内同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。用户线程只注册自己感兴趣的socket或者IO请求,然后去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率。
用户线程使用多路复用技术的伪代码:
{
select(socket);
while(1) {
sockets = select();
for(socket in sockets) {
if(can_read(socket)) {
read(socket, buffer);
process(buffer);
}
}
}
}
通过Reactor的方式,可以将用户线程轮询IO操作状态的工作统一交给handle_events事件循环进行处理。用户线程注册事件处理器之后可以继续执行做其他的工作(异步),而Reactor线程负责调用内核的select函数检查socket状态。当有socket被激活时,则通知相应的用户线程(或执行用户线程的回调函数),执行handle_event进行数据读取、处理的工作。由于select函数是阻塞的,因此多路IO复用模型也被称为异步阻塞IO模型。注意,这里的所说的阻塞是指select函数执行时线程被阻塞,而不是指socket。一般在使用IO多路复用模型时,socket都是设置为NONBLOCK的,不过这并不会产生影响,因为用户发起IO请求时,数据已经到达了,用户线程一定不会被阻塞。
void UserEventHandler::handle_event() {
if(can_read(socket)) {
read(socket, buffer);
process(buffer);
}
}
{
Reactor.register(new UserEventHandler(socket));
}
Reactor::handle_events() {
while(1) {
sockets = select();
for(socket in sockets) {
get_event_handler(socket).handle_event();
}
}
}
相关推荐
(1)同步阻塞IO(BlockingIO):即传统的IO模型。(2)同步非阻塞IO(Non-blockingIO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(NewIO)库。(3)IO多...
本文将从同步和异步的概念开始,然后介绍阻塞和非阻塞的区别,接着介绍阻塞IO和非阻塞IO的区别,最后介绍五种IO模型和两种高性能IO设计相关的设计模式(Reactor和Proactor)。 一、同步和异步 同步和异步是IO模型...
Java NIO,全称为New Input/Output,是Java在1.4...理解和掌握NIO,对于任何Java开发者来说,都能在开发高性能应用时游刃有余。在实际开发中,结合具体需求,灵活运用NIO,可以极大地提升应用程序的效率和响应速度。
下面本文先从同步和异步的概念 说起,然后接着阐述了阻塞和非阻塞的区别,接着介绍了阻塞IO和非阻塞IO的区别,然后介绍了同步IO和异步IO的区别,接下来介绍了5种IO模型,后介绍了两种和高性能IO设计相关的设计模式...
在Linux系统中,I/O多路复用技术如epoll是一种高效的进程间通信方式,用于管理多个文件描述符(FD)的状态。...在设计高性能的网络服务时,选择合适的触发模式和I/O模式至关重要,以优化系统资源利用率和响应速度。
理解Java IO的工作原理和相关知识点对于开发者来说至关重要,尤其是在进行系统级编程和高性能应用开发时。下面将详细阐述Java IO的一些核心概念和模型。 1. **用户空间与系统空间** 在Linux系统中,每个进程被划分...
Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。在本文中,我们将深入浅出地探讨 Netty 实现的 HTTP 协议栈,并通过实践来理解其工作原理。 首先,我们要...
而在非覆盖扫描中,IO Cost较高,因为每条记录都需要回表获取完整信息。 统计信息在查询优化中扮演着关键角色。MySQL Server层和InnoDB层都有相应的统计信息。Server层的统计信息包括CONST和VARIABLE,这些信息在表...
### MTK平台CAMERA驱动浅析 #### 一、手机CAMERA的物理结构: 手机摄像头(CAMERA)由多个部分组成,主要包括以下几个核心组件: - **FPC (Flexible Printed Circuit)**:柔性印刷电路板,用于连接摄像头各个部件...
此外,文章可能还涵盖了网络编程中的错误处理、并发连接管理、多线程或异步IO策略,以及性能优化等方面的知识。这些内容对于系统开发人员来说具有很高的参考价值,能帮助他们更好地理解和利用Linux的网络特性,开发...
IOCP是Windows操作系统提供的一种高度优化的异步I/O模型,常用于构建高性能的网络服务器,如TCP或UDP服务器。 描述中提到这是在网上找到的IOCP相关资料,目的是为从事这方面工作的人提供帮助。这些资料可能包含了...
此外,JAVA NIO(New IO)提供了一种非阻塞I/O模型,通过选择器(Selector)和通道(Channel)提高网络通信的效率。 文件与流是JAVA操作数据的重要手段。JAVA的File类提供了文件操作的基本功能,如创建、删除、...
Python是当今世界上最受欢迎的编程语言...了解并熟练掌握这两种并发模型,对于编写高效的Python程序至关重要。在实际开发中,我们还需要根据具体问题和需求,灵活运用线程池、进程池等高级工具,以达到最佳的性能效果。
Node.js 事件循环是其高性能并发模型的核心机制,确保了单线程环境下能够处理大量的并发操作。由于 Javascript 是单线程的,为了提高程序的执行效率和响应能力,Node.js 中的异步操作和事件循环就显得尤为重要。事件...
Node.js是一款允许JavaScript在服务器端运行的框架,近年来由于其出色的异步IO性能和轻量级特性,在构建高性能Web应用和网络服务方面备受青睐。然而,内存泄漏问题一直是Node.js应用开发中不可忽视的问题。内存泄漏...