没有无限的while循环,还有其他方法可以实现“监听”功能吗?

金敏俊

我一直在思考诸如React之类的代码和库,它们会自动,很好地响应事件的发生,并且想知道如何在较低级别的C ++和机器代码中实现所有这些。

我似乎无法弄清楚是否可以通过其他线程上运行的while循环来实现类似事件监听器的其他方式。

那么这一切都在幕后吗?只是一路循环下去?例如,例如RethinkDB,它自己宣传为具有repubsub的“实时数据库” “订阅”方法是否只是在幕后使用while循环实现的?我似乎找不到任何信息。

就像插座和东西一样。当计算机正在“侦听”套接字连接的端口时,该计算机是否正在运行类似以下内容的内容:

while(1) {
    if (connectionFound) {
        return True;
    }
}

还是我想念的东西?

slebetman

我将这个问题的答案写在另一个答案中。通常,我会以重复的形式关闭该问题,然后指向该答案,但这是一个非常不同的问题。另一个问题是关于javascript性能的问题。为了回答这个问题,我必须首先写下这个问题的答案。

因此,我将要做一些通常不应该做的事情:将部分答案复制到另一个问题上。所以这是我的答案:

javascript和node.js等待的实际事件根本不需要循环。实际上,它们需要0%的CPU时间。

异步I / O的工作方式(任何编程语言)

硬件

如果我们真的需要了解节点(或浏览器)内部的工作方式,那么不幸的是,我们必须首先了解计算机的工作方式-从硬件到操作系统。是的,这将是一次深潜,请耐心等待。

一切始于中断的发明。

这是一个伟大的发明,也是一个潘多拉魔盒-Edsger Dijkstra

是的,以上引用来自同一“ Goto认为有害” Dijkstra。从一开始就将异步操作引入计算机硬件被认为是一个非常困难的话题,即使对于业内的一些传奇人物而言。

引入了中断以加快I / O操作。硬件不需要将软件以无限循环的方式轮询某些输入(从而节省了CPU时间来完成有用的工作),而是向CPU发送信号以告知事件已发生。然后,CPU将挂起当前正在运行的程序并执行另一个程序来处理中断-因此我们将这些函数称为中断处理程序。“ handler”一词一直在堆栈中一直停留在GUI库中,GUI库将回调函数称为“事件处理程序”。

Wikipedia实际上有一篇不错的文章,关于中断,如果您不熟悉并且想了解更多信息:https : //en.wikipedia.org/wiki/Interrupt

如果您一直在关注,您会注意到中断处理程序的概念实际上是回调。您将CPU配置为在事件发生后的某个时间调用函数。因此,即使回调也不是一个新概念-它比C更旧。

中断使现代操作系统成为可能。没有中断,CPU将无法暂时停止程序以运行OS(嗯,这是协作式多任务处理,但现在暂时忽略它)。操作系统的工作方式是在CPU中设置硬件计时器以触发中断,然后告诉CPU执行程序。运行您的操作系统的正是此定时定时器中断。

除了计时器外,操作系统(或更确切地说是设备驱动程序)还为I / O设置了中断。发生I / O事件时,操作系统将接管您的CPU(或多核系统中的一个CPU),并检查其数据结构以处理下一步处理I / O的过程(这称为抢先式多任务处理)。

从键盘和鼠标存储到网卡的所有内容都使用中断来告诉系统要读取的数据。如果没有这些中断,监视所有这些输入将占用大量CPU资源。中断是如此重要,以至于它们通常被设计成USB和PCI等I / O标准。

工艺流程

现在,我们对此有了清晰的了解,我们可以了解节点/ javascript如何实际处理I / O和事件。

对于I / O,各种OS具有提供异步I / O的各种不同API-从Windows上的重叠I / O到Linux上的轮询/轮询,再到BSD上的kqueue到跨平台select()。Node在内部将libuv用作这些API的高级抽象。

尽管细节不同,但这些API的工作方式相似。本质上,它们提供了一个函数,当调用该函数时,它将阻塞您的线程,直到OS向其发送事件为止。因此,是的,即使非阻塞I / O也会阻塞您的线程。这里的关键是阻塞I / O将在多个位置阻塞您的线程,但非阻塞I / O仅在一个位置(您等待事件的位置)阻塞您的线程。

请查看我对另一个问题的回答,以获取有关此类API在C / C ++级别如何工作的更具体示例:我知道回调函数异步运行,但是为什么呢?

对于诸如按钮单击和鼠标移动之类的GUI事件,只需跟踪鼠标和键盘中断,然后将其转换为UI事件即可。这样可以释放您需要知道按钮,窗口,图标等位置的软件表格。

这允许您执行的操作是以面向事件的方式设计程序。这类似于中断使OS设计人员实现多任务处理的方式。实际上,异步I / O对框架来说是对OS的中断。它允许javascript花费正好0%的CPU时间来处理(等待)I / O。这就是使异步代码快速的原因-并不是真的更快,但不会浪费时间等待。

这个答案的期限很长,因此我将保留指向与此主题相关的其他问题的答案的链接:

Node js的体系结构和性能(注意:此答案提供了一些有关事件和线程之间关系的见解-tldr:操作系统在内核事件之上实现线程)

JavaScript是否使用弹性跑道算法进行处理

node.js服务器如何比基于线程的服务器更好

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

还有其他方法可以实现此代码,以便也使用zip函数吗?

除了适配器,还有其他方法可以将数据实现为活动吗?

我还有其他方法可以用来读取代码中的行以执行readLine()的功能吗?

Kotlin when(Pair <>),还有其他方法吗?

PHP还有很多其他方法吗?

Vue 多个 v-for 循环......还有其他方法吗

还有其他方法可以正确计算 Am 和 Pm 的时间吗?

除了使用nodetool status之外,还有其他方法可以获取cassandra hostid吗?

还有其他方法可以在php中创建pdf吗?

还有其他方法可以滤除excel中的空白吗?

还有其他方法可以为Visual Studio 2015构建opencv吗?

还有其他方法可以在javascript中获取对象属性吗?

除了alsactl存储之外,还有什么其他方法可以保存alsamixer设置吗?

除了 PHPUnit,还有其他方法可以测试 Symfony 应用程序吗?

除了身份验证之外,还有其他方法可以区分用户吗?

还有其他方法可以将数组的每个元素传递给函数吗?

还有其他方法可以定位绝对元素吗?

还有其他方法可以在Extjs中声明全局变量吗?

还有其他方法可以让Laravel重新加载环境变量吗?

还有其他方法可以解决R中的这个数学问题吗?

除了DAvg之外,还有其他方法可以找到平均值吗?

还有其他方法可以在pygame中加载图片吗?

在SwiftUI中无需使用GeometryReader,还有其他方法可以访问safeAreaInsets吗?

还有其他方法可以在 Ubuntu 上启动脚本吗?

除了 chroot jail 之外,还有其他方法可以限制 SSH 用户吗?

还有没有其他方法可以创建没有JSON的JavaScript关联数组?

还有其他方法可以避免在循环python(而不是groupby / transform)内部循环来避免重复结果吗?

在没有魔术助手的情况下,还有其他方法可以在 Assembly 中编写这些“数据”部分吗?

除了特征以外,还有其他方法可以向我不拥有的类型添加方法吗?