1

我知道这个标题听起来像是对其他十几个问题的欺骗,而且很可能是这样。然而,我已经阅读了这十几个问题,并在谷歌上搜索了一段时间,并没有找到任何让我满意的答案。

这可能是因为没有人正确回答,在这种情况下你应该投票给我。

这可能是因为我很愚蠢并且不理解其他答案(更有可能),在这种情况下你应该投票给我。

语境:

我知道 Node.js 中的 IO 操作被检测到并默认异步运行。我的问题是关于仍然可能长时间阻塞/运行的非 IO 操作。

假设我有一个blockingfunction带有for循环的函数,它可以执行加法或诸如此类的操作(纯 CPU 周期,没有 IO),还有很多。运行需要一分钟或更长时间。

假设每当有人向我的服务器发出特定请求时,我希望此功能运行。

问题:

显然,如果我在代码的外层显式调用这个循环,那么一切都会阻塞,直到它完成。

我读过的大多数建议都建议通过首先启动我所有的其他处理程序/服务器等,然后通过延迟调用函数来将其推迟到未来process.nextTickor setTimeout(blockingfunction, 0)

  • 但是不会blockingfunction1在执行循环的下一个旋转中阻塞吗?我可能错了,但似乎这样做会在不阻塞应用程序的情况下启动我的所有其他东西,但是当有人第一次发出导致blockingfunction被调用的请求时,只要完成,一切都会阻塞。

  • 放入blockingfunctiona setTimeoutor process.nextTickcall 是否以某种方式使其与未来的操作共存而不阻塞它们?

  • 如果没有,有没有办法在blockingfunction不重写的情况下做到这一点?

  • 其他人如何处理这个问题?我看到的很多答案都是“只要相信你的 CPU 密集型的东西会很快,它们会很快”,但这并不令人满意。

  • 没有线程(我可以保证执行blockingfunction将与其他正在发生的事情交错执行),我是否应该重新编写 CPU 密集型/耗时的循环以用于process.nextTick执行固定的、有保证的快速数量每滴答声的迭代次数?

4

2 回答 2

2

是的,即使您运行 process.nextTick,阻塞函数也会继续阻塞。

一些选项:

  1. 如果确实需要一段时间,那么也许应该将它分派到一个队列中,在那里你可以让一个专门的工作进程来处理它。

    1a。Node.js 有一个子进程风格,专门用于通过内置的通信通道来分叉其他 node.js 文件。因此,例如,您可以创建一个(或多个)线程来按顺序处理这些请求,然后响应并点击回调。请参阅:http ://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options

  2. 您可以将 blockingFunction 分解为循环运行的块。让它使用 process.nextTick 调用每 X 次迭代,以便为处理其他事件让路。

于 2012-12-20T22:36:00.837 回答
2

是的,你是对的。如果您将函数推迟到下一个刻度,它只会在该刻度而不是当前刻度中阻塞。

不幸的是,这里没有魔法可以为您解决这个问题。虽然可以在另一个进程中启动该功能,但这可能不值得麻烦,具体取决于您在做什么。

我建议以这样的方式重写你的函数,这样工作会发生一段时间,然后在下一个滴答声中继续。节点滴答非常有效......如果需要,您可以在一个体面大小的循环的每次迭代中调用它们,而无需大量开销。当然,您必须在代码中对其进行分析以查看其影响。

于 2012-08-05T16:24:01.200 回答