为什么 response.write 会阻塞线程?
why does response.write block the thread?
下面是示例:
const http = require('http')
const server = http.createServer()
const log = console.log.bind(console)
server.on('request', (req, res) => {
log('visited!')
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8',
})
for (let i = 0; i < 100000; i++) {
res.write('<p>hello</p>')
}
res.end('ok')
})
server.listen(3000, '0.0.0.0')
服务器在处理第一个请求时,线程阻塞,无法处理第二个请求。我想知道为什么会发生这种情况,因为 nodejs 使用事件驱动、非阻塞 I/O 模型。
好问题。
NodeJS 使用非阻塞 I/O 模型;也就是说,I/O 操作将 运行 在引擎盖下的单独线程上,但所有 JavaScript 代码将 运行 在同一事件循环驱动的线程上。
在您的示例中,当您要求 HTTP 服务器侦听传入请求时,Node 将在后台管理单独线程上的套接字侦听操作,以便您的代码可以在调用后继续 运行 server.listen()
.
当请求到来时,您的 server.on('request')
回调将在主事件循环线程上执行。如果另一个请求进来,它的回调不能 运行 直到第一个回调和当前在主线程上执行的任何其他代码完成。
大多数时候,回调是短暂的,因此您很少需要担心阻塞主线程。如果回调不是短暂的,它们几乎总是调用异步 I/O 相关函数,该函数实际上在引擎盖下的不同线程中执行 运行,因此释放主线程以供其他代码使用执行。
下面是示例:
const http = require('http')
const server = http.createServer()
const log = console.log.bind(console)
server.on('request', (req, res) => {
log('visited!')
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8',
})
for (let i = 0; i < 100000; i++) {
res.write('<p>hello</p>')
}
res.end('ok')
})
server.listen(3000, '0.0.0.0')
服务器在处理第一个请求时,线程阻塞,无法处理第二个请求。我想知道为什么会发生这种情况,因为 nodejs 使用事件驱动、非阻塞 I/O 模型。
好问题。
NodeJS 使用非阻塞 I/O 模型;也就是说,I/O 操作将 运行 在引擎盖下的单独线程上,但所有 JavaScript 代码将 运行 在同一事件循环驱动的线程上。
在您的示例中,当您要求 HTTP 服务器侦听传入请求时,Node 将在后台管理单独线程上的套接字侦听操作,以便您的代码可以在调用后继续 运行 server.listen()
.
当请求到来时,您的 server.on('request')
回调将在主事件循环线程上执行。如果另一个请求进来,它的回调不能 运行 直到第一个回调和当前在主线程上执行的任何其他代码完成。
大多数时候,回调是短暂的,因此您很少需要担心阻塞主线程。如果回调不是短暂的,它们几乎总是调用异步 I/O 相关函数,该函数实际上在引擎盖下的不同线程中执行 运行,因此释放主线程以供其他代码使用执行。