gpt4 book ai didi

javascript - Node.js 中的异步编程不应该导致 StackOverflow 吗?

转载 作者:行者123 更新时间:2023-11-30 08:12:01 25 4
gpt4 key购买 nike

我刚刚意识到(单线程)Node.js 的一个问题:

  1. 服务器开始响应请求,请求一直运行直到它因 I/O 而阻塞。

  2. 当请求处理器阻塞时,服务器启动并返回到第 1 步,处理更多请求。

  3. 每当请求处理器阻塞 I/O 时,服务器都会检查是否有任何请求已完成。它以 FIFO 顺序处理那些以响应客户端,然后像以前一样继续处理。

这是否意味着如果太多的请求开始互相阻塞而没有一个完成,#2 处应该有堆栈溢出?为什么/为什么不?

最佳答案

node.js 通过使用异步技术无处不在1 来防止您描述的堆栈过度增长。

任何可以阻塞的东西都使用回调进行进一步处理,而不是阻塞调用。这完全避免了堆栈增长,并且可以轻松地重新进入事件循环(“驱动”底层实际 I/O 和请求调度)。

考虑这个伪代码:

fun() {
string = net.read();
processing(string);
}

线程在读取时被阻塞,只有在读取完成并且处理完成后才能释放堆栈。

现在如果你所有的代码都是这样的:

fun() {
net.read(onDone: processing(read_data));
}

如果你像这样实现read:

net.read(callback) {
iorequest = { read, callback };
io.push_back(iorequest);
}

fun 一旦 read 可以使用关联的回调将读取 I/O 排队,就会完成。 fun 的堆栈在没有阻塞的情况下倒转 - 它“立即”返回事件循环,没有任何线程堆栈剩余。

即您可以继续进行下一个回调(重新进入事件循环),而无需在线程堆栈上保留任何每个请求的数据。

因此 node.js 通过在“用户”代码中发生阻塞调用的任何地方使用异步回调来避免堆栈过度增长。

有关此的更多信息,请查看 node.js 'about'页,以及最后链接的第一组幻灯片。

1好吧,差不多吧


你提到 QueueUserAPC在评论中。通过这种类型的处理,允许排队的 APC 阻塞,并且队列中的下一个 APC 在线程的堆栈上得到处理,使其成为“递归”分派(dispatch)。

假设我们有三个待处理的 APC(ABC)。我们得到:

初始状态:

Queue   ABC
Stack xxxxxxxx

线程休眠所以 APC 调度开始,进入 A 的处理:

Queue   BC
Stack AAAAxxxxxxxx

A block ,B 被分派(dispatch)在同一个堆栈上:

Queue   C
Stack BBBBBBAAAAxxxxxxxx

B 阻塞,C 被分派(dispatch):

Queue   
Stack CCCCCCCBBBBBBAAAAxxxxxxxx

很明显,如果有足够多的阻塞 APC 待处理,堆栈最终会爆炸。

使用 node.js,请求不允许阻塞。相反,这是对相同的三个请求会发生什么的模型:

Queue      ABC
Stack xxxxxxxx

A开始处理:

Queue      BC
Stack AAAAxxxxxxxx

现在 A 需要做一些阻塞的事情 - 在 node.js 中,它实际上不能。它所做的是对另一个请求 (A') 进行排队(大概有一个上下文——简单地说是一个包含所有变量的散列):

I/O queue  A'
Queue BC
Stack AAAAxxxxxxxx

然后 A 返回并且我们回到了:

I/O queue  A'
Queue BC
Stack xxxxxxxx

注意:没有更多的堆栈框架。 I/O 待定队列实际上由操作系统管理(使用 epollkqueue 或其他)。主线程检查事件循环中的操作系统 I/O 就绪状态和挂起(需要 CPU)队列。

然后 B 获得一些 CPU:

I/O queue  A'
Queue C
Stack BBBBBBBxxxxxxxx

同样的事情,B想做I/O。它对新的回调进行排队并返回

I/O queue  A'B'
Queue C
Stack xxxxxxxx

如果 B 的 I/O 请求同时完成,下一个快照可能看起来像

I/O queue  A'
Queue B'
Stack CCCCCxxxxxxxx

处理线程上的回调堆栈帧在任何时候都不会超过一个。 API 不提供阻塞调用,该堆栈不表现出 APC 模式所表现的递归增长类型。

关于javascript - Node.js 中的异步编程不应该导致 StackOverflow 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8868919/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com