有没有其他方法可以实现“聆听"?没有无限while循环的函数? [英] Is there any other way to implement a "listening" function without an infinite while loop?

查看:36
本文介绍了有没有其他方法可以实现“聆听"?没有无限while循环的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在思考像 React 这样的代码和库,它们可以在事件发生时自动做出反应,并且想知道所有这些是如何在 C++ 和机器代码的较低级别实现的.

I've been thinking a lot about code and libraries like React that automatically, well, react to events as they happen, and was wondering about how all of that is implemented at the lower levels of C++ and machine code.

我似乎想不出任何其他方式可以实现事件侦听器之类的东西,如果不是在另一个线程上运行 while 循环.

I can't seem to figure out any other way something like an event listener could be implemented with if not with a while loop running on another thread.

这一切都在幕后吗?只是 while 一直循环下去?例如,RethinkDB 将自己标榜为实时数据库",它具有 repubsub 图书馆.订阅"方法是否只是在后台使用 while 循环实现的?我似乎找不到任何相关信息.

So is that all this is under the hood? Just while loops all the way down? Like, for example, RethinkDB, which advertises itself as a "realtime database" that has the repubsub library. Is the "subscribe" method just implemented using a while loop under the hood? I couldn't seem to find any information on that.

比如,sockets 之类的.当计算机侦听"套接字连接的端口时,该计算机是否正在运行类似以下内容:

Like, sockets and stuff, too. When a computer is a "listening" on a port for a socket connection, is that computer just running something like:

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

还是我遗漏了什么?

推荐答案

我已将这个问题的答案写在另一个答案中作为旁白.通常我会将这个问题作为 重复并指出对于那个答案,但是这是一个非常不同的问题.另一个问题是关于 javascript 性能的.为了回答这个问题,我必须先写下这个问题的答案.

I've written the answer to this question as an aside in another answer. Normally I'd close this question as a duplicate and point to that answer however this is a very different question. The other question asked about javascript performance. In order to answer that I had to first write the answer to this question.

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

As such I'm going to do something that's not normally supposed to be done: I'm going to copy part of my answer to another question. So here's my answer:

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

Actual events that javascript and node.js waits on requires no looping at all. In fact they require 0% CPU time.

硬件

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

If we really need to understand how node (or browser) internals work we must unfortunately first understand how computers work - from the hardware to the operating system. Yes, this is going to be a deep dive so bear with me..

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

It was a great invention, but also a Box of Pandora - Edsger Dijkstra

是的,上面的引述来自同一个Goto 被认为有害"迪杰斯特拉.从一开始,将异步操作引入计算机硬件就被认为是一个非常困难的话题,即使对于行业中的一些传奇人物来说也是如此.

Yes, the quote above is from the same "Goto considered harmful" Dijkstra. From the very beginning introducing asynchronous operation to computer hardware was considered a very hard topic even for some of the legends in the industry.

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

Interrupts was introduced to speed up I/O operations. Rather than needing to poll some input with software in an infinite loop (taking CPU time away from useful work) the hardware will send a signal to the CPU to tell it an event has occurred. The CPU will then suspend the currently running program and execute another program to handle the interrupt - thus we call these functions interrupt handlers. And the word "handler" has stuck all the way up the stack to GUI libraries which call callback functions "event handlers".

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

Wikipedia actually has a fairly nice article about interrupts if you're not familiar with it and want to know more: https://en.wikipedia.org/wiki/Interrupt.

如果您一直在关注,您会注意到中断处理程序的这个概念实际上是一个回调.将 CPU 配置为在稍后发生事件时调用函数.所以即使是回调也不是一个新概念——它比 C 更古老.

If you've been paying attention you will notice that this concept of an interrupt handler is actually a callback. You configure the CPU to call a function at some later time when an event happens. So even callbacks are not a new concept - it's way older than C.

中断使现代操作系统成为可能.如果没有中断,CPU 将无法暂时停止您的程序运行操作系统(好吧,有协作多任务处理,但现在让我们忽略它).操作系统的工作原理是它在 CPU 中设置一个硬件定时器来触发中断,然后它告诉 CPU 执行您的程序.正是这个周期性的定时器中断运行您的操作系统.

Interrupts make modern operating systems possible. Without interrupts there would be no way for the CPU to temporarily stop your program to run the OS (well, there is cooperative multitasking, but let's ignore that for now). How an OS works is that it sets up a hardware timer in the CPU to trigger an interrupt and then it tells the CPU to execute your program. It is this periodic timer interrupt that runs your OS.

除了定时器,操作系统(或者更确切地说是设备驱动程序)为 I/O 设置中断.当 I/O 事件发生时,操作系统将接管您的 CPU(或多核系统中的 CPU 之一)并检查其数据结构,它接下来需要执行哪个进程来处理 I/O(这称为抢占式多任务处理).

Apart form the timer, the OS (or rather device drivers) sets up interrupts for I/O. When an I/O event happens the OS will take over your CPU (or one of your CPU in a multi-core system) and checks against its data structure which process it needs to execute next to handle the I/O (this is called preemptive multitasking).

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

Everything form keyboard and mouse to storage to network cards use interrupts to tell the system that there is data to be read. Without those interrupts, monitoring all those inputs would take a lot of CPU resources. Interrupts are so important that they are often designed into I/O standards like USB and PCI.

现在我们已经清楚地了解了这一点,我们可以理解 node/javascript 如何实际处理 I/O 和事件.

Now that we have a clear picture of this we can understand how node/javascript actually handle I/O and events.

对于 I/O,各种操作系统都有各种不同的 API 来提供异步 I/O - 从 Windows 上的重叠 I/O 到 Linux 上的轮询/epoll,再到 BSD 上的 kqueue 到跨平台的 select().Node 在内部使用 libuv 作为对这些 API 的高级抽象.

For I/O, various OSes have various different APIs that provide asynchronous I/O - from overlapped I/O on Windows to poll/epoll on Linux to kqueue on BSD to the cross-platform select(). Node internally uses libuv as a high-level abstraction over these APIs.

这些 API 的工作方式相似,但细节不同.本质上,它们提供了一个函数,当调用该函数时将阻塞您的线程,直到操作系统向其发送事件.所以是的,即使是非阻塞 I/O 也会阻塞你的线程.这里的关键是,阻塞 I/O 会在多个地方阻塞您的线程,但非阻塞 I/O 只会在一个地方阻塞您的线程——在那里您等待事件.

How these APIs work are similar though the details differ. Essentially they provide a function that when called will block your thread until the OS sends an event to it. So yes, even non-blocking I/O blocks your thread. The key here is that blocking I/O will block your thread in multiple places but non-blocking I/O blocks your thread in only one place - where you wait for events.

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

Check out my answer to this other question for a more concrete example of how this kind of API works at the C/C++ level: I know that callback function runs asynchronously, but why?

对于按钮单击和鼠标移动等 GUI 事件,操作系统只需跟踪您的鼠标和键盘中断,然后将它们转换为 UI 事件.这使您的软件表单无需知道按钮、窗口、图标等的位置.

For GUI events like button click and mouse move the OS just keep track of your mouse and keyboard interrupts then translate them into UI events. This frees your software form needing to know the positions of buttons, windows, icons etc.

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

What this allows you to do is design your program in an event-oriented manner. This is similar to how interrupts allow OS designers to implement multitasking. In effect, asynchronous I/O is to frameworks what interrupts are to OSes. It allows javascript to spend exactly 0% CPU time to process (wait for) I/O. This is what makes asynchronous code fast - it's not really faster but does not waste time waiting.

这个答案很长,所以我会留下我对与此主题相关的其他问题的答案的链接:

This answer is fairly long as is so I'll leave links to my answers to other questions that's related to this topic:

Node js 架构和性能(注意:这个答案提供对事件和线程关系的一点见解 - tldr:操作系统在内核事件之上实现线程)

Node js architecture and performance (Note: This answer provides a bit of insight on the relationship of events and threads - tldr: the OS implements threads on top of kernel events)

javascript 是否使用弹性赛道算法进行处理

node.js 服务器如何优于基于线程的服务器

这篇关于有没有其他方法可以实现“聆听"?没有无限while循环的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆