Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Node.js在线程池中维护线程时称为单线程?_Node.js_Event Loop - Fatal编程技术网

为什么Node.js在线程池中维护线程时称为单线程?

为什么Node.js在线程池中维护线程时称为单线程?,node.js,event-loop,Node.js,Event Loop,Node.js维护一个事件循环,但对于复杂的请求,默认情况下它也有四个线程。当线程池中有更多可用线程时,这是如何实现单线程的 此外,事件循环为复杂任务分配的线程是专用线程,那么它与其他多线程概念有何不同?默认情况下,JavaScript代码的执行在单个线程上运行 但是,node.js尝试使大多数长时间运行的调用异步。对于一些只涉及执行异步操作系统调用的线程,但对于其他一些线程,node.js将在辅助线程上执行调用本身,同时继续运行其他js代码。异步调用终止后,Js回调或Promise处理程序将运

Node.js维护一个事件循环,但对于复杂的请求,默认情况下它也有四个线程。当线程池中有更多可用线程时,这是如何实现单线程的


此外,事件循环为复杂任务分配的线程是专用线程,那么它与其他多线程概念有何不同?

默认情况下,JavaScript代码的执行在单个线程上运行


但是,node.js尝试使大多数长时间运行的调用异步。对于一些只涉及执行异步操作系统调用的线程,但对于其他一些线程,node.js将在辅助线程上执行调用本身,同时继续运行其他js代码。异步调用终止后,Js回调或Promise处理程序将运行。

在您所指的上下文中,“单线程”表示Javascript作为单线程运行没有两段Javascript同时运行无论是按字面意思还是按时间划分(注意:截止2020年,node.js现在有WorkerThreads,但这些与最初的讨论有所不同)。这大大简化了Javascript开发,因为不需要对Javascript变量进行线程同步,这些变量在不同的Javascript片段之间共享,因为同一时间只能运行一个Javascript片段

综上所述,node.js确实在其实现中使用了内部线程。您提到的默认四个线程用于磁盘I/O的线程池。因为磁盘I/O通常是操作系统级别的同步操作,阻止调用线程,node.js的设计中,所有I/O操作都应作为异步操作提供,node.js设计者决定通过使用线程池来实现异步接口,以便实现(在本机代码中)fs模块磁盘I/O接口(是的,在某些操作系统中存在非阻塞磁盘I/O操作,但node.js设计者决定不使用它们)。这一切都发生在本机代码中,不会影响Javascript只在单个线程中运行的事实

下面是node.js中磁盘I/O调用工作原理的总结。假设已经有一个打开的文件句柄

  • Javascript代码对现有文件句柄调用
    fs.write()
  • fs模块将参数打包到函数中,然后调用本机代码
  • 本机代码从线程池获取一个线程,并启动操作系统调用以将数据写入该文件
  • 本机代码从函数返回
  • fs模块从
    fs.write()调用返回
  • Javascript继续执行(在调用
    fs.write()
    之后出现的任何语句
  • 一段时间后,线程上的本机代码
    fs.write()
    调用完成。它获得一个保护事件循环的互斥锁,并在事件队列中插入一个事件
  • 当Javascript引擎执行完它正在运行的Javascript流时,它会检查事件队列以查看是否有任何其他事件要运行
  • 当它在事件队列中找到一个事件时,它会将其从事件队列中移除,并执行与该事件相关联的回调,从而启动一个新的运行Javascript流
  • 因为在当前Javascript流完成执行之前,不会对新事件进行操作,所以Javascript获取的是事件驱动的单线程性质,即使可以使用本机代码线程来实现某些库函数。这些线程用于将阻塞操作变为非阻塞操作,但不会执行影响Javascript执行本身的单线程性

    这里的关键是node.js是事件驱动的。触发某些Javascript运行的每个新操作都通过事件队列序列化,并且在当前Javascript流完成执行之前,不会为下一个事件提供服务



    在node.js体系结构中,让两个Javascript同时独立运行的唯一方法是为每个Javascript使用单独的node.js进程。然后,它们将作为两个完全独立的操作运行,操作系统将分别管理它们。如果您的计算机至少有两个内核,那么它们可以在同一时间运行e、 如果你的计算机只有一个内核,它们基本上都在自己的进程线程中,操作系统会对它们进行时间切片(它们之间共享一个CPU).

    对于异步处理,Node.js是作为实验明确创建的。人们相信,在典型的web负载下,通过在单个线程上执行异步处理,可以比典型的基于线程的实现实现实现更高的性能和可伸缩性。

    它不是线程。它们是子进程。子进程、进程和线程是不同的东西。所以事件循环是唯一的一个线程,如果有任何阻塞I/O,则由子进程负责!!我说的对吗?你能帮我提供一些链接,让我正确阅读此内容吗?谢谢:)作为旁注,如果你喜欢并发编程,请签出Go编程语言。它是并发的,并且是真正的多线程的,但是也是编译的和静态类型的。我误解了你的问题。我不是说Node.js的内部线程maintaiend。我说的是分叉过程。嗨,Yash,请用所有信息改进你的答案并分享来源,谢谢。