关于 NODE.js 并行线程 worker_threads 的使用与详解。

9 篇文章 0 订阅
1 篇文章 0 订阅

javascript 是单线程,那么node.js属于服务端语言改如何实现其他语言中的并发线程执行呢?在node V10只有 child_process,cluster的API来开启多子进程,多进程。进程并不是子线程,无法内存共享。在nodeV10后引入worker_threads API概念。

worker_threads

node官方文档注明了:

  • worker_threads 模块允许使用并行地执行 JavaScript 的线程。
  • 与 child_process 或 cluster 不同, worker_threads 可以共享内存。 它们通过传输 ArrayBuffer 实例或共享 SharedArrayBuffer 实例来实现。

所以我们看到worker_threads作用类似其他语言中的子线程并发执行,首先我们执行两段代码使用worker_threads和不使用worker_threads的区别。

模拟一个cpu密集计算 http 服务
const http = require('http')

const fork = () => {
    const startTime = new Date().getTime()
    for(let i = 0; i < 1000000000; i ++) {}
    const endTime = new Date().getTime()
    return `运算1000000000次,开始运算时间:${startTime},结束运算时间${endTime}`
}

const server = http.createServer((request, response) => {
    if(request.url === '/') {
        const result1 = fork() // 运算第一次
        const result2 = fork() // 运算第二次

        response.setHeader('content-Type', 'text/html; charset=utf-8')
        response.statusCode = 200
        response.end(`${result1} \n ${result2}`, 'utf-8')
    }
})

server.listen(8080, () => {
    console.log('启动成功')
})
然后我们打开浏览器访问 http://localhost:8080/

在这里插入图片描述

我们可以看到运算结果是依次进行的。那么我们来使用worker_threads进行优化看看结果

把程序中的密集计算工作提炼到另一个worker.js文中,因为worker_threads是以js文件来运行的。
// worker.js
const { parentPort } = require('worker_threads')

const startTime = new Date().getTime()
for(let i = 0; i < 1000000000; i ++) {}
const endTime = new Date().getTime()

parentPort.postMessage(`运算1000000000次,开始运算时间:${startTime},结束运算时间${endTime}`)
// http.js 修改
const http = require('http')
const { join } = require('path')
const { Worker } = require('worker_threads')

const server = http.createServer((request, response) => {
    if(request.url === '/') {
        response.setHeader('content-Type', 'text/html; charset=utf-8')
        response.statusCode = 200

        const wk1 = new Worker(join(__dirname, './worker.js'))
        const wk2 = new Worker(join(__dirname, './worker.js'))

        let result = ''
        const success = res => {
            if (result) // 判断是否已经接收到一次结果
                response.end(`${result} <br /> ${res}`, 'utf-8')
            else
                result = res
        }

        wk1.on('message', success)
        wk2.on('message', success)
    }
})

server.listen(8080, () => {
    console.log('启动成功')
})

访问http://localhost:8080/ 响应
在这里插入图片描述
从响应结果我们可以看到,两次运算都是并发执行的。上面parentPort API进行父级通信的api。具体更多api和使用大家可以到node官网进行了解

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨周龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值