EventLoop是一个很重要的概念,指的是计算机系统的一种运行机制。JavaScript语言就是利用这种机制来解决单线程运行带来的一些问题。本文参考了C.AaronCois的《Understanding The Node.js Event Loop》来解释什么是EventLoop,以及它与JavaScript语言的单线程模型有什么关系。要理解EventLoop,就要从程序的运行模式说起。运行后的程序称为“进程”。一般情况下,一个进程一次只能执行一个任务。如果要执行的任务很多,则只有三种解决方案。(1)队列。因为一个进程一次只能执行一个任务,所以它必须等待前面的任务执行完才能执行后面的任务。(2)创建新进程。使用fork命令为每个任务创建一个新进程。(3)创建新线程。由于进程过于占用资源,现在的程序往往允许一个进程包含多个线程,由线程完成任务。(关于进程和线程的详细解释,请看这里。)以JavaScript语言为例,它是一种单线程语言,所有任务都在一个线程上完成,即使用上面的第一种方法。一旦遇到大量任务或遇到耗时任务,网页就会出现“假死”,因为JavaScript无法停止,无法响应用户行为。你可能会问,为什么JavaScript是单线程的,就不能实现成多线程的吗?这与历史有关。JavaScript从一开始就是单线程的。原因大概是不想把浏览器弄得太复杂,因为多线程需要共享资源,可能会互相修改运行结果,这对于一个web脚本语言来说太复杂了。后来,JavaScript是一种单线程语言成为一种约定俗成。(WorkerAPI可以实现多线程,但JavaScript本身永远是单线程的。)如果一个任务是耗时的,比如涉及很多I/O(输入/输出)操作,那么线程的操作很可能是如下。上图绿色部分为程序运行时间,红色部分为等待时间。可以看出,由于I/O操作很慢,这个线程的大部分运行时间都在等待I/O操作的返回结果。这种操作模式称为“同步模式”(synchronousI/O)或“??阻塞模式”(blockingI/O)。如果你使用多线程,同时运行多个任务,很可能是这样的。上图可以看出,多线程不仅占用了多倍的系统资源,还空闲了多倍的资源,这显然是不合理的。EventLoop就是为了解决这个问题而提出的。维基百科是这样定义的:“EventLoopisaprogramstructureforwaitingandsendingmessagesandevents.(aprogrammingconstructthatwaitingforanddispatcheseventsormessagesinaprogram.)”简单来说,就是设置两个线程程序中:一个负责程序本身的运行,称为“主线程”;另一个负责主线程与其他进程(主要是各种I/O操作)的通信,称为“EventLoopthread”(可译为“消息线程”)。上图中主线程绿色部分仍然代表运行时间,而橙色部分代表空闲时间。每当遇到I/O时,主线程都会让EventLoop线程通知相应的I/O程序,稍后再运行,所以没有红色等待的时间。I/O程序完成操作后,EventLoop线程将结果返回给主线程。主线程调用预先设置的回调函数来完成整个任务。可以看出,由于多出橙色空闲时间,主线程可以运行更多的任务,提高了效率。这种运行模式称为“异步模式”(asynchronousI/O)或“??非阻塞模式”(non-blockingmode)。这正是JavaScript语言的工作原理。虽然单线程模型给JavaScript带来了很大的局限性,但也赋予了它其他语言所不具备的优势。如果部署得好,JavaScript程序是不会被阻塞的,这也是为什么node.js平台可以用极少的资源来应对大流量访问的原因。原文链接:http://www.ruanyifeng.com/blog/2013/10/event_loop.html
