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

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

我有一些混淆理解差异。 我觉得我有80%的理解,但还没有完全得到它。

线程模型将为每个请求产生一个新的线程。 这意味着你在计算和内存方面会花费相当多的开销。 一个事件循环运行在一个单独的线程中,这意味着你不会得到开销。

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

用于阻止I / O的伪示例:

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

非阻塞I / O的伪示例:

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

这个例子使用lambdas(匿名函数),就像它们在JavaScript中一直使用一样。 JS大量使用事件,这正是callback的意义所在。 一旦行动完成,触发事件触发callback。 这就是为什么它经常被称为一个平衡模型asynchronous模型

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

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

  • EventMachine (ruby)
  • 龙卷风 (Python)
  • node.js (V8服务器端JavaScript)

将传入的请求或callback看作是入队和处理的事件。

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

好处是,你不必等待自己的结果。 而是注册事件触发时执行的callback函数。 这允许框架处理I / O的东西,你可以很容易地依靠它的内部效率来处理长时间的行动,而不是自己阻止进程。

总之,万物都是平行的,但是你的代码。 永远不会有两个同时运行的callback函数片段 – 事件循环是单个线程。 在外部执行内容并最终传播事件的进程可以分布在多个线程/进程中。

一个平坦的循环可以让你处理与硬盘或networking交谈的时间。 拿这个时间表:

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

那个时候你在PHP中运行curl只是浪费CPU。