【问题标题】:nodejs run single or multi thread?nodejs运行单线程还是多线程?
【发布时间】:2021-02-20 15:29:15
【问题描述】:

我读过一些关于 nodejs 作为单线程工作的文章。它谈到 nodejs 在完成第一个请求后处理第二个请求。所以我尝试测试它。我有一些代码 this。然后我依次发送三个请求:

  1. http://localhost:3000/?wait=1 : start at **14:29:14**.469Z
  2. http://localhost:3000/?wait=1 : .........**14:29:19**.496Z
  3. http://localhost:3000/ : .........**14:29:15**.725Z

我不明白。我认为第三个请求应该在 14:29:19 开始,对吧?或者我误解了。请给我解释一下,谢谢大家!

【问题讨论】:

  • 即使您一次只能执行一条指令,您也可以等待并行处理。所有现代操作系统都有 API,允许您在不执行任何操作的情况下等待

标签: node.js


【解决方案1】:

Javascript(不仅是 node.js,甚至你的网络浏览器,无论它是 Chrome、Safari、IE 还是 Edge)都是单线程的。 javascript解释器的结构一般可以用如下伪代码来描述:

script_to_exec = compile_js_from_files()

do {

    event_queue = execute_javascript(script_to_exec)

    completed_events = wait_for_events()

    for_each (event from completed_events) {

        this_event = event_queue.find_one_matching(event)

        script_to_exec = this_event.callback
    }

} while (there_is_pending_events)

您可能会注意到上面的代码中根本没有线程代码。我们在wait_for_events() 中所做的只是使用操作系统提供的异步 I/O API。根据操作系统,这可能类似于 POSIX select() 或 Linux 和 OSX poll() 或 BSD epoll() 或 Windows 重叠 I/O 功能。 Node 使用 libuv 库,它会在编译时自动选择最佳 API。

循环第 1 轮

好的。所以第一轮循环它执行你的整个代码。这会在您设置 express 时设置 TCP 套接字侦听器。然后卡在wait_for_events()

第一个 HTTP 请求导致 wait_for_events() 返回。这会导致 Express 遍历您的中间件和路由列表以找到要执行的路由。它找到您的路线并调用wait(),后者调用setTimeout(),将其回调添加到计时器列表中。

循环第二轮

由于在await 返回之前没有更多的 javascript 可以执行,我们再次循环并再次卡在wait_for_events()

第二个 HTTP 请求导致 wait_for_events() 返回。这会导致 Express 遍历您的中间件和路由列表,并重复我之前描述的内容。

循环第 3 轮

由于在await 返回之前没有更多的 javascript 可以执行,我们再次循环并再次卡在wait_for_events()

第三个 HTTP 请求导致 wait_for_events() 返回。这会导致 Express 遍历您的中间件和路由列表,并重复我之前描述的内容。

循环第 4 轮

再次,我们再次循环并卡在wait_for_events()

第一个await wait() 计时器到期。这会导致wait_for_events() 返回并且javascript 确定事件是wait 的计时器,因此它会继续处理第一个HTTP 请求。这会导致 Express 发送响应。

循环第 5 轮

我们再次循环并等待wait_for_events()

第二个await wait() 计时器到期。这会导致wait_for_events() 返回并且javascript 确定该事件是该wait 的计时器,因此它会继续处理第二个HTTP 请求。这会导致 Express 发送响应。

循环第 6 轮

我们再次循环并等待wait_for_events()

第三个await wait() 计时器到期。这会导致 wait_for_events() 返回,并且 javascript 确定事件是该 wait 的计时器,因此它继续处理第三个 HTTP 请求。这会导致 Express 发送响应。

循环第 7 轮

我们再次循环,再次卡在wait_for_events() 等待更多 HTTP 请求...

总结

基本上,javascript 可以等待并行处理多个事情。这是因为它最初是一种 GUI 脚本语言,必须能够等待鼠标点击、键盘输入等。但它一次只能执行一条指令(当然,除非你故意使用功能执行额外的进程/线程,例如网络工作者或工作线程)。

如果您想知道为什么人们将 node.js 用于高性能 Web 服务器,我已经为这个相关问题写了一个答案,解释了为什么 node 速度快:Node js architecture and performance

以下是我的一些其他答案,涉及到有关异步执行的不同级别的详细信息:

I know that callback function runs asynchronously, but why?

Is my understanding of asynchronous operations correct?

Is there any other way to implement a "listening" function without an infinite while loop?

node js - what happens to incoming events during callback excution

I know that callback function runs asynchronously, but why?

【讨论】:

  • 我想指出,高性能异步单线程 Web 框架不仅仅适用于 node.js - 这正是 node/javascript 默认的工作方式。 Java 有 Play 框架可以做同样的事情,Python 有几个基于 Twisted 框架的 web 框架,它们的工作方式类似于 node。 Go 的 Gin 框架做了类似的事情,但如果我没记错的话,Go 自己的 goroutine 系统可以在单线程事件和多线程线程之间动态选择
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 2021-12-06
  • 1970-01-01
  • 2014-10-12
  • 1970-01-01
  • 2018-09-27
  • 2019-03-09
相关资源
最近更新 更多