Node.js学习1:事件循环探究

经常会在各类书籍中看到如下介绍:

    Nodejs的特征是异步式I/O和事件驱动,单线程由Nodejs自己管理,程序在执行时进入时间循环等待下一个事件的到来,每个异步I/O在执行完毕后会被推送到事件队列,等待程序进行处理

既然是单线程怎么实现异步IO呢?今天我们来刨一刨这句话~,首先我们介绍 下阻塞与线程,后文会经常出现,便于大家理解


  什么叫做阻塞?线程在执行过程中如果遇到I/O 操作(磁盘读写、网络通信等)通常要耗费比较长的时间,这时候操作系统会剥夺线程对CPU的控制权,使其暂停,并把资源让给其他线程,这种线程调度方式称为阻塞。当I/O操作完毕的时候,操作系统将这个线程的阻塞状态接触,恢复其对CPU的控制权,令其继续执行,这种模式称为同步I/O或者一部I/O

  非阻塞I/O(异步I/O)则针对所有的I/O操作采取不阻塞的策略,当线程遇到I/O操作时不会以阻塞的方式等待I/O操作结束,而是将I/O请求发送给操作系统,继续执行后面的语句。当操作系统完成I/O操作后以事件的形式通知执行I/O操作的线程,线程会在特定的时间处理这个事件。为了处理异步I/O必须有时间循环,不断检查是否有未处理的事件,依次予以处理。

  在阻塞模式下,一个线程只能处理一个任务,要想提高吞吐量必须通过多线程。而在非阻塞模式下,一个线程永远在执行计算操作,所以这个线程的CPU核心利用率永远是100%,减少了多线程中创建线程、线程切换带来的事件消耗。


  上一段代码解释问题

var fs = require('fs');
fs.readFile("txt/io.txt","UTF-8",function(err,data){
  if(err){
    console.log(err);
  }else{
    console.log(data);
  }
});
console.log("读取文件完毕。。。。");
  大家肯定知道答案,因为readFile是一个异步I/O操作,按照上文说的非阻塞原理先输出I/O后面的代码,等readFile()操作执行完毕后操作系统发送一个事件给执行readFile的线程,线程在回调函数里执行后续操作,输出结果如下

读取文件完毕。。。。
hello world !

   上一张图片

  

  打个比方

   Nodejs在执行过程中会维护一个事件循环队列,程序在执行过程中进入事件循环列等待下一个事件到来,每个异步式I/O请求完成后都会被推送到事件队列,等待程序进行处理。而且Nodejs是单线程的,但是Nodejs所处的环境是多线程的,你调用的Nodejs功能可能是有底层C++的多个服务提供的,但是同一时刻系统只运行你的一个Nodejs事件回调函数。也就是说,除了你的Nodejs程序,其他所有的程序都是多线程的。

  举个例子,我们写的js代码就像是一个国王,而nodejs给国王提供了很多仆人。早上,一个仆人叫醒了国王,问他有什么需要。国王给他一份清单,上面列举了所有需要完成的任务,然后睡回笼觉去了。当国王回去睡觉之后,仆人才离开国王,拿着清单,给其它的仆人一个个布置任务。仆人们各自忙各自的去了,直到完成了自己的任务后,才回来把结果禀告给国王。国王一次只召见一个人,其它的人就在外面排着队等着。国王处理完这个结果后,可能给他布置一个新的任务,或者就直接让他走了,然后再召见下一个人。等所有的结果都处理完了,国王就继续睡觉去了。直接有新的仆人完成任务后过来找他。这就是国王的幸福生活。在nodejs中,有一个队列(先进先出),保存着一个个待执行的任务。第一个任务就是我们写的js代码,它最先被执行(相当于国王给第一个仆人任务清单)。在它执行完以后(国王睡回笼觉去了),其它的任务才会加到队列上(相当于第一个仆人按照清单给其它仆人分配任务)。


  适应场景

  由于Nodejs的以上特性,使他特别适合非计算密集且并发访问量要求严格的场景。如聊天服务器,综合服务类网站或者电子商务网站服务器。具体点说:当应用程序需要处理大量的输入/输出而在客户端发出响应之前,应用程序并不需要进行复杂的处理的场景。

  还有,传统的服务器端语言(如,Java PHP)为每个客户连接创建一个新的线程(约为2M),理论上8G的内存服务器可以同时连接的最大用户为4000,。可以看出,一个主要的平静就是服务器所支持的最大同时连接用户。

  Nodejs修改了客户端到服务器的连接方法,因为她并不是为每个用户连接创建一个线程,避免了线程的切换,而是为每个客户端连接触发一个在Nodejs内部进行处理的事件,同样8G内存的服务器可以同时连接的最大用户量变为了几万。





 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值