nodejs中使用worker_threads来创建新的线程的方法

下面详细讲解如何在Node.js中使用worker_threads模块来创建新线程。

简介

在Node.js中,JavaScript语言具有单线程执行的特性,这意味着如果主线程执行某些任务时,会阻塞其他任务的执行进度,导致性能瓶颈。因此,可以使用worker_threads模块创建新线程,实现多线程执行任务的目的。Worker对象执行的代码并不在主线程中运行,所以它们不会阻塞主线程。

创建Worker

使用worker_threads模块创建Worker的基本语法如下:

const { Worker } = require('worker_threads');

const worker = new Worker(workerDataFile, options);

其中,workerDataFile是一个要在工作线程中运行的JS文件,而options是Workers工作条件的配置项。这样就可以创建出一个新的Worker对象,可以在这个对象上调用一些方法控制它的行为。

Worker线程的生命周期

创建Worker后,会自动创建一个新线程来执行传入的workerDataFile代码,直到它停止或被终止。Worker线程的完整生命周期如下:

  • new Worker():创建Worker对象;
  • Worker.on('message', message => {}):监听Worker线程发送的消息;
  • Worker.on('error', error => {}):监听Worker线程的错误;
  • Worker.on('exit', code => {}):监听Worker线程的退出;
  • Worker.postMessage():向Worker线程发送消息;
  • Worker.terminate():立即关闭Worker线程。

示例1:异步计算

我们来看一个Worker的示例。在这个示例中,我们创建了一个用于计算斐波那契数列的Worker。

创建一个名为calFibonacci.js的文件,代码如下:

const { parentPort } = require('worker_threads');

function fibonacci(n) {
  if (n === 0 || n === 1) {
    return n;
  } else {
    return fibonacci(n-1) + fibonacci(n-2);
  }
}

parentPort.on('message', (num) => {
  const result = fibonacci(num);
  parentPort.postMessage(result);
});

上述代码中,我们从worker_threads模块中引入parentPort对象,在这个对象上监听由主线程发来的消息。当我们收到一条消息时,就会计算斐波那契数列并将结果通过parentPort.postMessage()方法发送回主线程。

接下来,我们在主线程中创建Worker。

const { Worker } = require('worker_threads');
const path = require('path');

const worker = new Worker(path.join(__dirname, 'calFibonacci.js'));

worker.on('message', (result) => {
  console.log('计算结果:', result);
});

const num = 40;
worker.postMessage(num);
console.log('主线程计算中...');

上述代码中,我们使用path.join()方法创建Worker的workerDataFile参数,将斐波那契数列计算的工作交给Worker线程。当Worker线程完成计算后,会将结果通过worker.postMessage()方法发送回来。在主线程中,我们通过监听Worker的message事件来获取计算结果。执行这段代码后,可以看到如下输出:

主线程计算中...
计算结果: 102334155

可见,Worker线程成功地完成了斐波那契数列的计算并返回了结果。

示例2:文件读写

我们可以在Worker线程中完成磁盘IO等阻塞式操作,并让主线程继续执行不相关的工作。例如,一个计算密集型的应用程序可在一个Worker中运行而在主线程中处理IO。

在这个示例中,我们将创建一个文件读写工具,用于读取文件并将其内容写入新文件。我们将创建一个名为fileIO.js的文件用于处理此任务。

const fs = require('fs');
const { parentPort } = require('worker_threads');

const fileIO = (inputFilePath, outputFilePath) => {

  const readStream = fs.createReadStream(inputFilePath, { encoding: 'utf-8' });
  const writeStream = fs.createWriteStream(outputFilePath, { encoding: 'utf-8' });

  readStream.on('error', error => {
    console.error(`读取文件 '${inputFilePath}' 失败`, error);
    parentPort.postMessage({
      status: 'failed',
      msg: `读取文件 '${inputFilePath}' 失败`
    });
  });

  writeStream.on('error', error => {
    console.error(`写入文件 '${outputFilePath}' 失败`, error);
    parentPort.postMessage({
      status: 'failed',
      msg: `写入文件 '${outputFilePath}' 失败`
    });
  });

  writeStream.on('close', () => {
    parentPort.postMessage({
      status: 'success',
      inputFilePath,
      outputFilePath
    });
  });

  readStream.pipe(writeStream);
};

parentPort.on('message', (data) => {
  const { inputFilePath, outputFilePath } = data;
  fileIO(inputFilePath, outputFilePath);
});

上述代码中,我们从worker_threads模块中引入parentPort对象,接收由主线程发来的消息。当我们收到一条消息时,会将读取的文件结果写入新文件。如果其中任何一步操作出错,就向主线程发送一个消息。

接下来,我们在主线程中创建Worker。

const { Worker } = require('worker_threads');
const path = require('path');

const worker = new Worker(path.join(__dirname, 'fileIO.js'));

worker.on('message', (result) => {
  console.log(result);
});

const inputFilePath = path.join(__dirname, 'input.txt');
const outputFilePath = path.join(__dirname, 'output.txt');

worker.postMessage({
  inputFilePath,
  outputFilePath
});
console.log(`开始读写文件, input文件路径: ${inputFilePath}, output文件路径: ${outputFilePath}`);

上述代码中,我们使用path.join()方法创建Worker的workerDataFile参数,将文件读写的操作交给Worker线程。当Worker线程完成任务后,会将结果通过worker.postMessage()方法发送回来。在主线程中,我们通过监听Worker的message事件来获取计算结果。执行这段代码后,可以看到如下输出:

开始读写文件, input文件路径: /usr/local/nodeproject/input.txt, output文件路径: /usr/local/nodeproject/output.txt
{ status: 'success',
  inputFilePath: '/usr/local/nodeproject/input.txt',
  outputFilePath: '/usr/local/nodeproject/output.txt' }

可见,Worker线程成功地完成了文件读写任务,并成功的写入了新文件,同时向主线程发送了成功的消息。

以上就是关于如何在Node.js中使用worker_threads模块来创建新线程的详细攻略,希望可以对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:nodejs中使用worker_threads来创建新的线程的方法 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • JS对象创建的几种方式整理

    JS对象创建的几种方式整理的攻略如下: 1. 对象字面量方式 对象字面量方式是指直接使用 {} 创建对象,使用键值对的方式来描述对象的属性和属性值。示例如下: const person = { name: "Alice", age: 25, sayHi: function() { console.log("Hi, I’m &qu…

    JavaScript 2023年5月27日
    00
  • JavaScript数据类型的存储方法详解

    JavaScript数据类型的存储方法详解 1. JavaScript数据类型简介 在JavaScript中,共有以下七种数据类型: 原始类型:Number、String、Boolean、null、undefined、Symbol 引用类型:Object 2. 数据类型的存储方式 2.1 原始类型的存储方式 原始类型的数据直接存储在栈内存中,它们的值可以直接…

    JavaScript 2023年6月11日
    00
  • JavaScript中undefined和is not defined的区别与异常处理

    JavaScript中undefined与is not defined的区别与异常处理攻略 在JavaScript编程中,我们可能会遇到两种情况:一个是使用undefined变量,一个是使用未定义的变量(is not defined)。虽然在表象上看起来很相似,但实际上它们是不同的,并且需要不同的处理方法。在这篇攻略中,我将向您展示它们的区别,以及如何在代码…

    JavaScript 2023年5月18日
    00
  • 两种简单的跨域方法(jsonp、php)

    这里就给您详细讲解跨域方法中的jsonp和php。 一、JSONP跨域 概述 JSONP是一种简单的跨域方式,它通过动态添加<script>标签,利用浏览器允许跨域请求资源的特性获取外域的数据,并将数据作为参数传递给回调函数,从而实现跨域获取数据。 实现步骤 在页面中定义一个全局函数,作为回调函数。 通过动态创建<script>标签的…

    JavaScript 2023年5月27日
    00
  • 一文搞懂JavaScript数组的特性

    前言 数组是几乎所有编程语言的基础语法,JavaScript因为语法特性,之前缺少一些集合类对象,对数组的使用就会更多一些,因此我们更需要理解数组知识。然而大部分人对数组都已经非常熟悉了,所以本文将不会介绍数组的基础语法和用法,而是从JavaScript中数组的一些特殊之处入手,通过这些少有特性的详细介绍,加深我们对数组的理解。 基本介绍 首先,作为开始,我…

    JavaScript 2023年4月24日
    00
  • JavaScript表单验证的两种实现方法

    下面是详细讲解JavaScript表单验证的两种实现方法的攻略。 一、方法一:使用HTML5表单验证 在HTML5中,可以使用一些input标签的属性进行简单的表单验证。 1. 必填项验证 首先介绍一个必填项验证的属性,即required属性。将该属性设置在input标签中,可以让表单中的该输入框变为必填项。 示例代码: <form> <l…

    JavaScript 2023年6月10日
    00
  • 荐书|您有一份JavaScript书单待签收

    针对“荐书|您有一份JavaScript书单待签收”的完整攻略,我提供以下说明: 标题 “荐书|您有一份JavaScript书单待签收”是一个建议性的标题,用于丰富内容的表现形式,提高文章的可读性,引起读者的兴趣。 简介 在文章的开头,应该简要介绍文章的主题和目标受众,例如:“这篇文章主要介绍JavaScript方面的书单,旨在帮助读者更好地学习JavaSc…

    JavaScript 2023年5月19日
    00
  • 解析javascript中鼠标滚轮事件

    下面是解析 JavaScript 中的鼠标滚轮事件的完整攻略: 什么是鼠标滚轮事件? 鼠标滚轮事件(mousewheel 事件)指的是当用户通过鼠标滚轮滚动时触发的事件。在 JavaScript 中,我们可以使用 mousewheel 事件来监听用户的鼠标滚轮操作。 如何监听鼠标滚轮事件? 在 JavaScript 中,可以通过以下两种方式来监听鼠标滚轮事件…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部