什么是事件循环,它与使用其他模型有什么不同?

时间:2021-11-05 02:32:48

I have been looking into Node.JS and all the documentation and blogs talk about how it uses an event-loop rather than a per-request model.

我一直在研究Node。JS和所有的文档和博客都在讨论如何使用事件循环而不是每个请求模型。

I am having some confusion understanding the difference. I feel like I am 80% there understanding it but not fully getting it yet.

我搞不懂其中的区别。我觉得我有80%的时间理解它,但还没有完全理解它。

3 个解决方案

#1


17  

A threaded model will spawn a new thread for every request. This means that you get quite some overhead in terms of computation and memory. An event loop runs in a single thread, which means you don't get the overhead.

线程模型将为每个请求生成一个新的线程。这意味着在计算和内存方面会产生相当大的开销。事件循环在一个线程中运行,这意味着您不会获得开销。

The result of this is that you must change your programming model. Because all these different things are happening in the same thread, you cannot block. This means you cannot wait for something to happen because that would block the whole thread. Instead you define a callback that is called once the action is complete. This is usually referred to as non-blocking I/O.

这样做的结果是您必须更改编程模型。因为所有这些不同的事情都发生在同一个线程中,所以不能阻塞。这意味着您不能等待某些事情发生,因为这会阻塞整个线程。相反,定义一个回调,该回调在操作完成后调用。这通常称为非阻塞I/O。

Pseudo example for blocking I/O:

阻塞I/O的伪示例:

row = db_query('SELECT * FROM some_table');
print(row);

Pseudo example for non-blocking I/O:

非阻塞I/O的伪示例:

db_query('SELECT * FROM some_table', function (row) {
  print(row);
});

This example uses lambdas (anonymous functions) like they are used in JavaScript all the time. JS makes heavy use of events, and that's exactly what callbacks are about. Once the action is complete, an event is fired which triggers the callback. This is why it is often referred to as an evented model or also asynchronous model.

这个例子使用了lambdas(匿名函数),就像在JavaScript中一直使用它们一样。JS大量使用事件,这正是回调的意义所在。操作完成后,触发回调的事件将被触发。这就是为什么它经常被称为事件模型或异步模型。

The implementation of this model uses a loop that processes and fires these events. That's why it is called an event queue or event loop.

该模型的实现使用一个循环来处理和触发这些事件。这就是为什么它被称为事件队列或事件循环。

Prominent examples of event queue frameworks include:

事件队列框架的突出例子包括:

  • EventMachine (Ruby)
  • EventMachine(Ruby)
  • Tornado (Python)
  • 龙卷风(Python)
  • node.js (V8 server-side JavaScript)
  • 节点。js(V8服务器端JavaScript)

#2


6  

Think of incoming requests or callbacks as events, that are enqueued and processed.

将传入的请求或回调视为事件,并将其加入队列并进行处理。

That is exactly the same what is done in most of the GUI systems. The system can't know when a user will click a button or do some interaction. But when he does, the event will propagated to the event loop, which is basically a loop that checks for new events in the queue and process them.

这与在大多数GUI系统中所做的事情完全相同。系统无法知道用户何时会单击按钮或进行一些交互。但当他执行时,事件将传播到事件循环,该循环基本上是一个循环,检查队列中的新事件并处理它们。

The advantage is, that you don't have to wait for results for yourself. Instead, you register callback functions that are executed when the event is triggered. This allows the framework to handle I/O stuff and you can easily rely on it's internal efficiency when dealing with long-taking actions instead of blocking processes by yourself.

好处是,你不必等待结果。相反,您可以注册在事件被触发时执行的回调函数。这使框架能够处理I/O内容,在处理长时间执行的操作时,您可以很容易地依赖它的内部效率,而不是您自己阻塞进程。

In short, everythings runs in parallel but your code. There will never be two fragments of callback functions running concurrently – the event loop is a single thread. The processes that execute stuff externally and finally propagate events however can be distributed in multiple threads/processes.

简而言之,除了代码之外,所有东西都是并行运行的。永远不会有两个同时运行的回调函数片段——事件循环是一个线程。但是,外部执行内容并最终传播事件的进程可以分布在多个线程/进程中。

#3


0  

An evented loop allows you to handle the time it takes to talk to the hard drive or network. take this list of time:

事件循环允许您处理与硬盘或网络对话所需的时间。看看这个时间列表:

Source | CPU Cycles
L1     | 3 Cycles
L2     | 14 Cycles
RAM    | 250  Cycles
Disk   | 41,000,000 Cycles
Network| 240,000,000 Cycles

That time you're running curl in PHP is just wasting CPU.

在PHP中运行curl只是在浪费CPU时间。

#1


17  

A threaded model will spawn a new thread for every request. This means that you get quite some overhead in terms of computation and memory. An event loop runs in a single thread, which means you don't get the overhead.

线程模型将为每个请求生成一个新的线程。这意味着在计算和内存方面会产生相当大的开销。事件循环在一个线程中运行,这意味着您不会获得开销。

The result of this is that you must change your programming model. Because all these different things are happening in the same thread, you cannot block. This means you cannot wait for something to happen because that would block the whole thread. Instead you define a callback that is called once the action is complete. This is usually referred to as non-blocking I/O.

这样做的结果是您必须更改编程模型。因为所有这些不同的事情都发生在同一个线程中,所以不能阻塞。这意味着您不能等待某些事情发生,因为这会阻塞整个线程。相反,定义一个回调,该回调在操作完成后调用。这通常称为非阻塞I/O。

Pseudo example for blocking I/O:

阻塞I/O的伪示例:

row = db_query('SELECT * FROM some_table');
print(row);

Pseudo example for non-blocking I/O:

非阻塞I/O的伪示例:

db_query('SELECT * FROM some_table', function (row) {
  print(row);
});

This example uses lambdas (anonymous functions) like they are used in JavaScript all the time. JS makes heavy use of events, and that's exactly what callbacks are about. Once the action is complete, an event is fired which triggers the callback. This is why it is often referred to as an evented model or also asynchronous model.

这个例子使用了lambdas(匿名函数),就像在JavaScript中一直使用它们一样。JS大量使用事件,这正是回调的意义所在。操作完成后,触发回调的事件将被触发。这就是为什么它经常被称为事件模型或异步模型。

The implementation of this model uses a loop that processes and fires these events. That's why it is called an event queue or event loop.

该模型的实现使用一个循环来处理和触发这些事件。这就是为什么它被称为事件队列或事件循环。

Prominent examples of event queue frameworks include:

事件队列框架的突出例子包括:

  • EventMachine (Ruby)
  • EventMachine(Ruby)
  • Tornado (Python)
  • 龙卷风(Python)
  • node.js (V8 server-side JavaScript)
  • 节点。js(V8服务器端JavaScript)

#2


6  

Think of incoming requests or callbacks as events, that are enqueued and processed.

将传入的请求或回调视为事件,并将其加入队列并进行处理。

That is exactly the same what is done in most of the GUI systems. The system can't know when a user will click a button or do some interaction. But when he does, the event will propagated to the event loop, which is basically a loop that checks for new events in the queue and process them.

这与在大多数GUI系统中所做的事情完全相同。系统无法知道用户何时会单击按钮或进行一些交互。但当他执行时,事件将传播到事件循环,该循环基本上是一个循环,检查队列中的新事件并处理它们。

The advantage is, that you don't have to wait for results for yourself. Instead, you register callback functions that are executed when the event is triggered. This allows the framework to handle I/O stuff and you can easily rely on it's internal efficiency when dealing with long-taking actions instead of blocking processes by yourself.

好处是,你不必等待结果。相反,您可以注册在事件被触发时执行的回调函数。这使框架能够处理I/O内容,在处理长时间执行的操作时,您可以很容易地依赖它的内部效率,而不是您自己阻塞进程。

In short, everythings runs in parallel but your code. There will never be two fragments of callback functions running concurrently – the event loop is a single thread. The processes that execute stuff externally and finally propagate events however can be distributed in multiple threads/processes.

简而言之,除了代码之外,所有东西都是并行运行的。永远不会有两个同时运行的回调函数片段——事件循环是一个线程。但是,外部执行内容并最终传播事件的进程可以分布在多个线程/进程中。

#3


0  

An evented loop allows you to handle the time it takes to talk to the hard drive or network. take this list of time:

事件循环允许您处理与硬盘或网络对话所需的时间。看看这个时间列表:

Source | CPU Cycles
L1     | 3 Cycles
L2     | 14 Cycles
RAM    | 250  Cycles
Disk   | 41,000,000 Cycles
Network| 240,000,000 Cycles

That time you're running curl in PHP is just wasting CPU.

在PHP中运行curl只是在浪费CPU时间。