事出有因

为何选择event loop?

Event Loop是一种推进无阻塞I/O(网络、文件或跨进程通讯)的软件模式。传统的阻塞编程也是用一样的方式,通过function来调用I/O。但进程会在该I/O操作结束前卡住不动,下面的这段伪代码可以演示阻塞I/O的情况:

var post = db.query('SELECT * FROM posts where id = 1');  // 这行后面的指令都无法执行,除非等到这行指令执行完毕
doSomethingWithPost(post);
doSomethingElse();

这里都发生了什么呢?当数据库查询被执行时,整个进程/线程都闲置下来,等待查询操作的响应,我们称之为阻塞。数据查询的响应可能要花费上千个CPU周期,这段时间内,整个进程都处于不可用状态。进程在数据库操作完成前就白白等待下去,浪费了让它来着手处理其它客户端请求的机会。

这种编程方式将不允许你来并行处理I/O(例如同时执行另一个数据库查询或与远程web服务进行通讯),导致调用栈被冻结了,傻傻等候数据库服务的回应。

这里有两个可实现的解决方案能让进程在这种等候期间保存忙碌——创建更多的调用栈,或者使用事件回调。

Why?

Why the event loop?

The Event Loop is a software pattern that facilitates non-blocking I/O (network, file or inter-process
communication). Traditional blocking programming does I/O in the same fashion as regular function
calls; processing may not continue until the operation is complete. Here is some pseudo-code that
demonstrates blocking I/O:
1 var post = db.query('SELECT * FROM posts where id = 1');
2 // processing from this line onward cannot execute until the line above completes
3 doSomethingWithPost(post);
4 doSomethingElse();
What is happening here? While the database query is being executed, the whole process/thread
idles, waiting for the response. This is called blocking. The response to this query may take many
thousands of CPU cycles, rendering the entire process unusable during this time. The process could
have been servicing other client requests instead of just waiting for the database operation to
complete.
Programming in this way does not allow you to parallelize I/O (such as performing another database
query or communicating with a remote web service). The call stack becomes frozen, waiting for the
database server to reply.
This leaves you with two possible solutions to keep the process busy while it’s waiting: create more
call stacks or use event callbacks.
原文

相关文章: