sle*_*vin 8 multithreading asynchronous event-handling node.js
我已经使用了Node.js一段时间了,我才意识到它可以阻塞.我无法将我的大脑包裹在Node.js阻塞的条件下.
因此,由于异步回调,I/O任务是非阻塞的,但是单个线程可能是阻塞的,因为它是同步的,因为事件循环可能被卡住,因为很多复杂的请求同时出现?
非常感谢.
首先,要明确:node.js作为一个整体不是单线程的.Node通过libuv确实有一个线程池,它用于执行某些任务,这些任务目前无法从大多数平台上的单个线程(例如文件I/O)有效地执行,或者它们本身就是计算密集型的(例如zlib).应该注意的是,大多数crypto模块(其本身也是计算密集型)当前没有异步/非阻塞接口(除了crypto.randomBytes()).
v8还利用多个线程来执行垃圾收集,函数优化等操作.
但是,节点中的其他所有内容确实发生在同一个单线程中.
现在具体解决您的问题:
javascript代码从单个线程运行的事实不会使节点阻塞.正如这个答案所解释的那样,node最重要的是(I/O)并发而不是(代码)并行.您可以通过利用内置cluster模块并行运行节点代码,例如在多核/ CPU系统上,但节点的主要目标是能够同时处理大量I/O而无需为每个插槽/服务器专用一个线程/等等.
这是一个很好的,详细的书面记录这里描述的节点事件循环是如何工作的.
如前所述,Node的主要目标是非常好地处理I/O,这适用于Web应用程序和任何类型的网络程序的大多数用例.
如果您的脚本受CPU约束(例如,您正在计算pi或转码音频/视频),那么最好将该工作委托给节点中的子进程(例如,调用ffmpeg转码而不是在javascript或同步中进行转码)在节点的主线程上的c ++节点插件中).如果您没有同时执行任何其他操作(例如处理HTTP请求),您可以在进程中阻止这些操作.有许多人将以这种方式使用节点来执行各种实用程序任务,其中I/O并发性并不重要.其中一个示例可能是执行js和css文件的缩小,linting和/或捆绑的脚本,或者是从大量图像集创建缩略图的脚本.
但是,如果您的脚本改为创建TCP或HTTP服务器,例如从数据库中提取信息,对其进行格式化并将其发送回用户,那么节点将擅长这样做,因为在此过程中花费了大部分时间只是等待套接字/ HTTP客户端发送(更多)数据并等待数据库回复查询结果.