因此,我对Node.js的工作方式有所了解:它具有一个侦听器线程,该线程接收事件,然后将其委托给工作池。工作线程一旦完成工作,便会通知侦听器,然后侦听器将响应返回给调用者。
我的问题是:如果我在Node.js中建立一个HTTP服务器,并在我的一个路由路径事件(例如“ / test /
sleep”)中调用sleep,那么整个系统就会停顿下来。甚至是单个侦听器线程。但是我的理解是这段代码正在工作池中发生。
现在,相比之下,当我使用Mongoose与MongoDB交谈时,数据库读取是一项昂贵的I /
O操作。Node似乎能够将工作委托给线程并在完成时接收回调。从数据库加载所需的时间似乎不会阻塞系统。
Node.js如何决定使用线程池线程还是侦听器线程?为什么我不能编写仅休眠并阻塞线程池线程的事件代码?
您对节点如何工作的理解是不正确的……但这是一个普遍的误解,因为这种情况的实际情况实际上相当复杂,并且通常归结为诸如“ node is single
threaded”之类的小词,过分简化了事情。
目前,我们将忽略通过集群和webworker-
threads进行的显式多处理/多线程,而仅讨论典型的非线程节点。
节点在单个事件循环中运行。它是单线程的,您只能获得一个线程。您编写的所有JavaScript都会在此循环中执行,并且如果该代码中发生了阻塞操作,则它将阻塞整个循环,直到完成为止,其他任何事情都不会发生。这是您经常听到的节点的典型单线程性质。但是,这还不是全部。
通常使用C / C ++编写的某些功能和模块支持异步I /
O。当您调用这些函数和方法时,它们在内部管理将调用传递给工作线程。例如,当您使用fs
模块请求文件时,fs
模块将该调用传递给工作线程,而该工作线程等待其响应,然后将其呈现回事件循环,该循环在没有它的情况下一直在进行与此同时。所有这些都是从您(节点开发人员)那里抽象出来的,其中一些是通过使用libuv从模块开发者那里抽象出来的。
正如Denis
Dollfus在评论中指出的(,libuv用于实现异步I /
O的策略并不总是线程池,特别是在http
模块的情况下,另一种策略似乎是目前使用。就我们的目的而言,最重要的是要注意如何实现异步上下文(通过使用libuv),并且libuv维护的线程池是该库提供的实现异步的多种策略之一。
在一篇非常相关的切线上,这篇出色的文章对节点如何实现异步性以及一些相关的潜在问题以及如何处理这些问题进行了更深入的分析。它的大部分内容是在我上面写的内容基础上扩展的,但另外指出:
UV_THREADPOOL_SIZE
环境变量增加线程池的大小来缓解这种情况,只要您在需要并创建线程池之前就这样做即可:process.env.UV_THREADPOOL_SIZE = 10;
如果您希望在节点中进行传统的多处理或多线程处理,则可以通过内置cluster
模块或上述其他各种模块来获取webworker- threads
,也可以通过实现某种方式将工作分块并手动使用setTimeout
或进行伪造。setImmediate
或process.nextTick
暂停您的工作并在以后的循环中继续进行,以完成其他过程(但不建议这样做)。
请注意,如果您使用javascript编写长时间运行/阻止的代码,则可能是在犯错误。其他语言将更有效地执行。
问题内容: 奇怪的是: 似乎或多或少被定义为。通过这种方式很容易产生错误: 一些fname意外地以else块结尾。修复很简单,我们应该改用它,但是从表面上看,这似乎是一种不错的pythonic方式,并且比“正确”的方式更具可读性。 由于字符串是不可变的,所以为什么字符串错误是什么技术细节?什么时候进行身份检查更好,什么时候进行平等检查更好? 问题答案: 据我所知,检查对象身份是否相等。由于没有强制
问题内容: 我有一个将客户发送到另一个站点来处理付款的应用程序。客户之外的另一个站点在我们的服务器上调用一个页面,让我们知道付款的状态。被调用页面会检查付款应用程序提供的参数,并检查我们是否知道该交易。然后,它更新数据库以反映状态。这一切都无需与客户进行任何互动即可完成。 我个人选择将此功能实现为JSP,因为将文件拖放到文件系统中比编译和打包文件然后将条目添加到配置文件中要容易得多。 考虑到页面的
问题内容: 我知道Deamon是后台线程。我们可以通过调用创建自己的守护程序线程。 我的问题是:为什么以及何时需要将我们的线程创建为守护程序线程? 问题答案: 当所有正在运行的线程都是守护程序线程时,JVM将退出。因此,想象一下您正在编写一个简单的游戏,其中您的主要方法一直循环直到您决定退出为止。想象一下,在游戏开始时,您启动了一个线程,该线程将不断轮询某些网站以触发警报。当您决定结束游戏时,您希
问题内容: 我怎么能说: 为什么函数调用中不需要括号,而最后一行呢? 问题答案: 是一个功能 调用该函数并产生该函数返回的任何值。 setTimeout的目的是在一段时间后运行代码。你需要的功能只是传递给它(这样的setTimeout可以自称在适当的时候函数),因为如果你将它传递给setTimeout的前调用的函数(用括号),将执行 现在 而不是1秒后,。
一般来说,当发现 CPU 的占用率和实际业务应该出现的占用率不相符,或者对 Nginx worker 的资源使用率(CPU,内存,磁盘 IO )出现怀疑的情况下,都可以使用火焰图进行抓取。另外,对 CPU 占用率低、吐吞量低的情况也可以使用火焰图的方式排查程序中是否有阻塞调用导致整个架构的吞吐量低下。 常用的火焰图有三种: lj-lua-stacks.sxx 用于绘制 Lua 代码的火焰图 sam
本文向大家介绍SVM中什么时候用线性核什么时候用高斯核?相关面试题,主要包含被问及SVM中什么时候用线性核什么时候用高斯核?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 当数据的特征提取的较好,所包含的信息量足够大,很多问题是线性可分的那么可以采用线性核。若特征数较少,样本数适中,对于时间不敏感,遇到的问题是线性不可分的时候可以使用高斯核来达到更好的效果。