《深入浅出Node.js》学习笔记(2)异步I/O

本文介绍了操作系统处理I/O的基本方式——阻塞与非阻塞I/O的区别,以及非阻塞I/O如何通过轮询提高性能。此外,还探讨了Node.js中如何利用线程池模型实现跨平台的非阻塞异步I/O,以及其事件循环机制的工作原理。

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

理解异步/同步与非阻塞/阻塞

异步/同步与非阻塞/阻塞其实是两回事。操作系统内核处理I/O只有两种方式:阻塞与非阻塞。

  • 阻塞I/O调用之后需要等待系统内核完成所有操作后,调用才能结束。阻塞I/O造成CPU等待,浪费了CPU的处理能力。
  • 非阻塞I/O调用之后会立即返回,CPU的时间片可以用来处理其他事务。立即返回造成的结果是,返回时并没有数据,因为完整数据需要I/O操作完成才能获取,因此需要轮询。

    轮询方式有许多种,一个比较好的方式是*nux下的epoll轮询(图片来自书籍):
    epoll轮询
    系统将对任何设备的I/O操作抽象为对文件的I/O。进入轮询时,应用层检查文件描述符上的事件状态,如果没有I/O事件,将会进行休眠,直到事件发生唤醒。这种事件通知机制使得CPU不必花费大量计算用于重复轮询,提高了性能。

遗憾的是,非阻塞I/O是系统内核层面的实现,对于应用程序而言,依然是一种同步。另外,不同系统内核对非阻塞I/O的支持度不一,因此Node使用了线程池模型来实现非阻塞异步I/O。

异步I/O
当主线程需要进行I/O操作时,在线程池创建I/O线程,I/O线程以非阻塞或阻塞I/O的方式向系统内核获取数据。数据获取完成后,通过线程通信异步通知主线程,这样就实现了跨平台的异步I/O。

事件循环

Node进程开启后,会创建一个类似while(true)的循环:
事件循环
从图中可以看到这个机制类似于android中Looper的设计。每次循环都会检查是否存在事件需要处理,如果有,则取出一个事件,并检查事件是否有相关联的回调。如果有回调,则执行回调。当不存在需要处理的事件时,该循环退出。另一方面,事件源的设计遵循观察者模式。文件I/O、网络请求调用时,会产生一个特定类型的事件,被对应的观察者接收。事件循环检查这些观察者,每次”消费”一个事件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值