本文是个人在实际开发和学习中对nodejs的一些理解,现整理出来方便日后查阅,如果能给您启发将不胜荣幸。
非阻塞I/O
I/O:即 Input / Output,一个系统的输入和输出。
一个系统可以理解为一个个体,比如说一个人,你说话就是输出,你听就是输入。
阻塞 I/O 与非阻塞 I/O 的区别就在于系统接收输入再到输出期间,能不能接收其他输入。
下面以两个例子来说明什么是阻塞 I/O 和非阻塞 I/O:
1.打饭
首先我们要确定一个系统的范围,在这个例子中食堂阿姨和餐厅的服务生看成是一个系统,输入就是点菜,输出就是端菜。
那么在点菜和端菜之间能不能接受其他人的点菜,就可以判断是阻塞I/O还是非阻塞I/O。
对于食堂阿姨,他在点菜的时候,是不能帮其他同学点菜的,只有这个同学点完菜端菜走了之后,才能接受下一个同学的点菜,所以食堂阿姨是阻塞I/O。
对于餐厅服务员,他可以在点完菜以后,这个客人端菜之前是可以服务下一位客人的,所以服务员是非阻塞I/O。
2.做家务
在洗衣服的时候,是不需要等着洗衣机旁边的,这个时候可以去扫地和整理书桌,当整理完书桌后衣服也洗好了,这个时候去晾衣服,那么总共只需要25分钟。
洗衣服其实就是一个非阻塞I/O,在把衣服扔进洗衣机和洗完衣服期间,你是可以干其他事情的。
非阻塞I/O之所以能提升性能,是因为它可以把不必要的等待给节省掉。
理解非阻塞I/O的要点在于:
- 确定一个进行I/O的系统边界。这非常关键,如果把系统扩大,上面餐厅的例子,如果把系统扩大到整个餐厅,那么厨师肯定是一个阻塞 I/O。
- 在 I/O 过程中,能不能进行其他 I/O。
nodejs的非阻塞 I/O
nodejs的非阻塞 I/O 是怎么体现的呢?前面说过理解非阻塞 I/O 的一个重要点是先确定一个系统边界,nodejs的系统边界就是主线程。
如果下面的架构图按照线程的维护划分,左边虚线部分是nodejs线程,右边虚线部分是c++线程。
现在 nodejs 线程需要去查询数据库,这是一个典型的 I/O 操作,它不会等待 I/O 的结果,而且继续处理其他的操作,它会把大量的计算能力分发到其他的c++线程去计算。