node.js异步逻辑行为

时间:2013-12-15 08:19:45

标签: multithreading node.js

我正在构建一个CPU密集型Web应用程序,在C ++编写CPU密集型内容时,在node.js中编写Web服务器。 node.js将通过插件连接到c ++。我对一件事感到困惑 -

假设每个请求的CPU密集型操作的时间是5秒(这可能涉及反转一个巨大的矩阵)。当这个请求通过时,绑定到c ++的node.js会将此请求发送到c ++代码。

现在这是否意味着node.js在接下来的5秒内不会被捕获并且可以继续提供其他请求?

我很困惑,因为我听说即使节点提供异步功能,它仍然是单线程的。

显然我不希望node.js被推迟5s,因为这是一个巨大的代价。想象一下这个密集操作同时有100个请求。

3 个答案:

答案 0 :(得分:2)

尝试理解JS回调和异步逻辑,我遇到了以下描述的许多不同版本;

  

作为参数传递给另一个函数的回调函数运行   跟随时间过程传递给它的函数。

这种困境起源于"时间拍摄"形容词。比如是

  • 由于CPU处于空闲状态并等待响应而占用时间?
  • 由于CPU正忙于数字运算,所以需要时间吗?

这在说明中并不清楚,让我很困惑。所以我尝试了以下两个代码。



getData('http://fakedomain1234.com/userlist', writeData);

document.getElementById('output').innerHTML += "show this before data ...";

function getData(dataURI, callback) {
    // Normally you would actually connect to a server here.
    // We're just going to simulate a 3-second delay.
    var timer = setTimeout(function () {
        var dataArray = [123, 456, 789, 012, 345, 678];
        callback(dataArray);
    }, 3000);
}

function writeData(myData) {
    document.getElementById('output').innerHTML += myData;
}

<body>
    <p id="output"></p>
</body>
&#13;
&#13;
&#13;

&#13;
&#13;
getData('http://fakedomain1234.com/userlist', writeData);

document.getElementById('output').innerHTML += "show this before data ...";

function getData(dataURI, callback) {
    var dataArray = [123, 456, 789, 012, 345, 678];
    for (i=0; i<1000000000; i++);
    callback(dataArray);
}

function writeData(myData) {
    document.getElementById('output').innerHTML += myData;
}
&#13;
<body>
    <p id="output"></p>
</body>
&#13;
&#13;
&#13;

因此在两个代码中都有一段时间在getData函数中进行活动。在第一个CPU中,CPU处于空闲状态,在第二个CPU中,CPU处于忙碌状态。很明显,当CPU繁忙时,JS运行时不是异步的。

答案 1 :(得分:1)

Node的主要线程是JS事件循环,因此与JS交互的所有逻辑都是单线程的。这还包括通过JS直接触发的任何C ++逻辑。

通常,任何长时间运行的任务都应该拆分为工作进程。例如,在您的情况下,您可以使用一个工作进程来排队计算,并在完成后将事件发送回JS线程。

实际上,这是关于如何处理connected to c++ via addons代码的问题。

答案 2 :(得分:0)

我不会参考Node.js的具体内容,因为我不熟悉内部架构及其允许的可能性(但据我所知,它支持多个工作线程,每个线程代表一个不同的事件循环)

一般情况下,如果您需要处理100秒可靠的CPU时间,那么除了确保您有500个处理器可用之外,您无能为力。

如果100个请求/ s达到峰值,而平均值会低得多,那么解决方案就是排队,你可以使用队列来吸收这个打击。

现在事情开始变得有趣,因为它不是5秒实时CPU时间,而是0.1 CPU时间和4.9等待或介于两者之间。在这种情况下,应该使用异步处理来将所有等待时间用于工作。

在这种情况下异步意味着:

  • 所有执行都发生在事件循环中。
  • 不等待没有睡眠没有阻止I / O ,只是执行或返回事件循环。
  • 您将任务拆分为非阻塞子任务,与(异步)事件(例如,带有响应)交错,继续执行。
  • 您将系统拆分为多个事件处理服务,通过异步事件交换请求和响应,并协作以提供整体功能。

如果您有一个子系统怎么办?根据上述原则,您无法转变为异步服务?

答案是用队列(以吸收请求)+多个线程(允许执行其他线程正在等待的某些线程)包装它,提供其余子系统所期望的异步事件请求/响应接口。

在所有情况下,最好保留有限数量的线程(而不是每个请求的线程模型),并始终将系统中活动/热线程的总数保持在该数字之下处理资源。

Node.js很不错,因为它的输入/输出本质上是异步的,并且所有的基础设施都是为了实现我上面描述的那些东西。