如何为工作线程创建池

时间:2019-05-26 20:50:13

标签: javascript node.js

我一直在学习Node.js中的实验性worker threads模块。我已经阅读了官方文档以及大多数可用的文章,这些文章仍然很少。

我创建了一个简单的示例,该示例生成十(10)个工作线程,以便生成10,000个SHA256摘要,然后对其进行数字签名。

使用十(10)个工人大约需要两(2)秒才能产生全部10,000。没有工人,大约需要十五(15)秒。

在官方文档中指出,建议创建一个工人池,而不是按需生成工人。

我试图找到有关如何进行此操作的文章,但到目前为止我还没有运气。

如何创建工作线程池?是否会以某种方式修改worker.js文件,以便我可以提前创建Workers,然后向其发送消息,这将导致他们执行其代码?该池是特定于用例的,还是可以创建一个可以加载文件或其他东西并处理任何用例的通用池?

谢谢。

主要

const { performance } = require('perf_hooks')
const { Worker } = require('worker_threads')        

// Spawn worker
const spawn = function spawnWorker(workerData) {
  return new Promise((resolve, reject) => {
    const worker = new Worker('./worker.js', { workerData })
    worker.on('message', (message) => resolve(message))
    worker.on('error', reject)
    worker.on('exit', (code) => {
      if (code !== 0)
        reject(new Error(`Worker stopped with exit code ${code}`))
    })
  })
}

const generate = async function generateData() {
  const t0 = performance.now()
  const initArray = []
  for (step = 1; step < 10000; step += 1000) {
    initArray.push({
      start: step,
      end: step + 999
    })
  }
  const workersArray = initArray
    .map(x => spawn(x))
  const result = await Promise.all(workersArray)

  let finalArray = []
  for (let x of result) {
    finalArray = finalArray.concat(x.data)
  }
  const t1 = performance.now()
  console.log(`Total time: ${t1 - t0} ms`)
  console.log('Length:', finalArray.length)
}

generate()
  .then(x => {
    console.log('EXITING!')
    process.exit(0)
  })

工人

const { performance } = require('perf_hooks')
const { workerData, parentPort, threadId} = require('worker_threads')
const crypto = require('crypto')
const keys =  require('./keys')

const hash = function createHash(data) {
  const result = crypto.createHash('sha256')
  result.update(data, 'utf8')
  return result.digest('hex')
}

const sign = function signData(key, data) {
  const result = crypto.createSign('RSA-SHA256')
  result.update(data)
  return result.sign(key, 'base64')
}

const t0 = performance.now()
const data = []
for (i = workerData.start; i <= workerData.end; i++) {
  const digest = hash(i.toString())
  const signature = sign(keys.HTTPPrivateKey, digest)
  data.push({
    id: i,
    digest,
    signature,
  })
}
const t1 = performance.now()

parentPort.postMessage({
  workerData,
  data,
  time: t1 - t0,
  status: 'Done',
 })

1 个答案:

答案 0 :(得分:0)

我建议使用 workerpool。它基本上为您完成所有池管理,并且支持工作线程和集群。