如何编写利用线程的Node.js代码?

时间:2016-07-06 09:50:57

标签: node.js v8 libuv

所以这是我对节点如何工作的理解:

  • 执行所有JS代码的单线程。
  • IO /网络呼叫利用场景后面的线程池。 (使用libuv这是一个C ++ lib)
  • 一旦IO操作完成,它的回调就会被推回回调队列,并且回调可以在下一个时间点被事件循环拾取。

我想了解的是如何编写可以利用系统线程的代码?我是用C / C ++编写一个lib并为它提供Javascript绑定吗?

假设我有一些操作/功能,它不需要IO但是CPU密集型,所以我想在多个线程中运行它。我如何在Node中做到这一点?

3 个答案:

答案 0 :(得分:0)

我的理解是这不能用Node完成。当然,您可以用另一种语言编写程序并编写一些绑定,但Node本身不支持多线程。您可以使用多程序编程:启动Node程序的多个实例并通过HTTP交换消息。然后,您的操作系统将处理不同CPU核心上的程序实例的分发。

答案 1 :(得分:0)

Well Node使用libuv,它实现了一个线程池。请阅读here以获得更好的解释。要从文章中挑选一些见解

  

libuv库维护node.js使用的线程池   在后台执行长时间运行的操作,不会阻塞   它的主线。有效地,在幕后,node.js是   基于线程的,无论你喜不喜欢。

那么也许可以研究libuv如何做到这一点,以及它如何与Node交互,并以此为基础构建自己的方法?

This answer很好地解释了一些内容,展示了一些libuv代码,并引用了另一个great article on libuv

答案 2 :(得分:0)

单线程节点是一种常见的误解。事实要复杂得多。虽然Node Event Loop是单线程的,但Node标准库中包含的某些功能不是单线程的。

我们运行的Node内包含的某些功能在事件循环之外运行,因此在该单线程之外运行。

因此,我们在Node中编写的许多代码并未完全在该单线程内执行。

您可以通过编写代码来进行自我测试,这些代码可以通过实现<script src="http://code.jquery.com/jquery-3.3.1.slim.min.js"></script> <link href="http://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script> <script src="http://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/> <body> <div class="bg-primary navbar-stripes"></div> <nav class="navbar navbar-expand-md navbar-light bg-warning" > <div class="container"> <a href="index.html" class="navbar-brand"> <img src="https://i.imgur.com/1c8K4fu.png" alt="" class="img-fluid"> </a> <div class="row"> <h1 class="text-white d-none d-lg-block">Brisol Futsal Club</h1> </div> <button class="navbar-toggler" data-toggle="collapse" data-target="#navbarCollapse"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarCollapse"> <ul class="navbar-nav ml-auto"> <li class="nav-item active"> <a href="index.html" class="nav-link">Home</a> </li> <li class="nav-item"> <a href="about.html" class="nav-link">About Us</a> </li> <li class="nav-item"> <a href="players.html" class="nav-link">Players</a> </li> <li class="nav-item"> <a href="sponsors.html" class="nav-link">Sponsors</a> </li> <li class="nav-item"> <a href="contact.html" class="nav-link">Contact</a> </li> </ul> </div> </div> </nav> <div class="bg-success navbar-stripes"></div> </body>模块中的pbkdf2函数来证明并非所有Node都是真正的单线程。

您可以对crypto函数运行所需的时间进行基准测试,以了解线程和线程池在计算机上的实际运行情况。因此,您可以创建各种pbkdf2函数来表示线程。该函数将执行一些昂贵的工作,您可以对其进行基准测试并使用它来检测Node是否为单线程,如下所示:

pbkdf2

此功能需要花费相当长的时间才能运行,因此在大多数2015年中期的MacBook Pro中约为1秒。

因此,上面的回调函数正在计算哈希,同样,使用我在上面指出的计算机再次完成该哈希应该不超过1秒,但是该函数的作用并不像在计算机上执行所需的时间那么重要。

您可以添加更多的函数调用来表示更多的线程,也可以像const crypto = require('crypto'); const start = Date.now(); crypto.pbkdf2('a', 'b', 100000, 512, 'sha512', () => { console.log('1:', Date.now() - start); }); 那样调整计算机线程池中的线程池大小。