【发布时间】:2012-01-15 10:10:47
【问题描述】:
我刚刚意识到(单线程)Node.js 存在问题:
服务器开始响应请求,并且请求一直运行直到它因为 I/O 而阻塞。
当请求处理器阻塞时,服务器会启动并返回到第 1 步,处理更多请求。
每当请求处理器阻塞 I/O 时,服务器都会检查是否有任何请求完成。它按 FIFO 顺序处理这些以响应客户端,然后像以前一样继续处理。
如果太多的请求开始相互阻塞并且没有一个完成,这是否意味着在#2 处应该存在堆栈溢出?为什么/为什么不?
【问题讨论】:
-
为所有请求共享相同的“堆栈”是完全不切实际的——这怎么可能适用于单个线程和多个请求?我猜每个请求都有自己的堆分配(或等效)状态。
-
@Mat:QueueUserAPC 之类的东西很有可能——只是在某个点之后它会爆炸。所以你怀疑 JS 根本没有真正使用 CPU 堆栈来服务线程?
-
您链接到的那个函数不会向线程的 CPU 堆栈添加任何内容,它会将内容添加到(单独分配的)队列中。 node.js 可以很好地使用这种技术,尽管它们可能会使用可移植的东西(而且很可能是自产的)。试着想出一种方法来在你上面描述的场景中使用实际的 CPU 堆栈,你会发现它不起作用。
-
@Mat: 不,它确实工作 -- 每当线程在警报状态下休眠时(例如使用WaitForSingleObjectEx),任何排队的 APC 都会在线程上调用,然后等待对
WAIT_IO_COMPLETION感到满意。效果很好。 -
这不是重点。排队的对象不会放在线程的 CPU 堆栈上。线程(暂时)被转移到处理队列中存储的对象。它的 CPU 堆栈用于此目的,但这只是一个额外的帧。当一个排队的对象被处理时,堆栈返回到它的初始状态(并且该进程重新启动)。使用这种技术不存在使堆栈爆裂的风险(只要 1. 当进程被警告时堆栈不是“满的”并且 2. 数据处理本身不会爆裂它)。取决于排队的数据(项目的大小或 n°),线程堆栈不会增加。
标签: javascript node.js