npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

node-threadobject

v1.0.2

Published

let node support multi threads in js codes

Downloads

11

Readme

Node-threadobject

deprecate Use muti-thread instead. 使用 C++ 技术写扩展,写起来比较难。muti-thread 模块是一个更好的解决方案,只需要用 Js 实现函数即可享受多线程的编程模型.

Node 在富计算场景下可能会遇到瓶颈(好比用一条腿走路)。 node-threadobject 是一个 C++ 模块,用来实现在 Js 代码中创建线程,并将复杂的计算任务委托给新线程执行。

在 Js 代码中创建线程对象,执行 CPU 密集型函数,例如计算大文件 HASH,加密解密等任务。可扩展 C++ 模块的处理函数,处理不同的复杂计算任务。在多核环境下,线程对象有助于更好的分配 node 集群中各个线程的 CPU 占用,以可控的方式减少线程等待和阻塞主线程。

例如,在双核环境下,一个线程对象使得其与主线程各运行于一个 CPU。在这种情况下,如果有两个线程对象处理计算任务,则主线程有 66% 的机会争取到运行。与使用线程池相比,能够精确预期。

在具体的场景中,例如使用 node 构建区块链(Block chain)的 P2P 网络,协议使得主线程面临着 CPU 计算的压力,比方说计算大块数据的 HASH。未经扩展的 node 在此类情景下可能遇到瓶颈。node-threadobject 是解决此类问题的通用方法。

此外,对于数据密集型业务,有可能引起频繁 GC,无法有效利用内存,例如 Buffer 与 String 的互转。如果考虑使用原生模块的技术处理,可有效减轻引擎负担。

同时,支持在新开的 V8 虚拟机里安全的运行一段 Js 代码。

node-threadobject is a package for providing ability to create new threads in js. It helps you consciously assign cpu-bound tasks to a limited number of CPUs.

Follow me on github!

支持的操作系统(Platform Support)

Windows, Linux and OS X

需要的 Node 版本 (Node engine)

>=4.0.0

编译链接(Compile & Link)

先全局安装 node-gyp
在工程根目录下运行 node-gyp configure
在工程根目录下运行 node-gyp rebuild
(编译过程大概需要 10s 左右,如果出现提示无权访问目录,请尝试 sudo node-gyp rebuild)

npm install -g node-gyp
node-gyp configure
node-gyp build (or  **sudo node-gyp rebuild** )

How it works

参考了 chrome 浏览器的线程模型(chrome thread model),每个线程内部包含了一个 C++ 闭包队列(C++ closure queue),按序处理任务。

增加更多的计算型函数 (Add more computational types of functions)

只需要增加新的文件,然后将头文件增加到rcib.h中。hash 是一个例子,它是一个无状态型的计算任务,file 是另外一个例子。增加新的计算型函数不需要修改 rcib(run codes in background) 目录里面的代码。

src/rcib 这个目录下的代码经过精心构建,通常扩展本模块不需要动里面的东西。

src/file 这是一个有状态计算型任务的范例。

src/hash 这是一个无状态计算任务的范例。

安装使用(Usage)

npm install node-threadobject (or  **sudo npm install node-threadobject** )

例子(Examples)

将一个定时器抛给线程对象,等待2秒钟后,回到主线程执行回调函数。内部使用64位表示时间,支持以小时为单位的大定时器

var Thread = require('node-threadobject');
var thread = new Thread();

thread.delayBySec(2, function(err){
  if(err)
    console.error(err);

  console.log('after two secs');
  thread.close();
  console.log('thread running state: ' + thread.isRunning());
  thread = null;
  });

console.log('thread running state: ' + thread.isRunning());

/*
result:
    thread running state: true
    after two secs
    thread running state: false
*/

在另一个线程中计算一个文件的 HASH 值

/*
 see test/example/sha2.js
*/
'use strict';

var path = require('path');
var fs = require('fs');
var assert = require('assert');
var Thread = require('node-threadobject');
var thread = new Thread();
thread.set_encode('base64');

console.log('HASH 计算之前');
fs.readFile('./test/thread.js', function(err, data) {
  thread.sha2({data, type: 256}, function(err, data){
    if(err) return console.error(err);
    console.log('HASH 计算结果');
    console.log(data);
    console.log('HASH 计算之后');
    console.log('正在排队处理的任务数:' + thread.numOfTasks());
  });
  console.log('正在排队处理的任务数:' + thread.numOfTasks());
});

/*
result:
    HASH 计算之前
    正在排队处理的任务数:1
    HASH 计算结果
    drK1C69gYX9I8qYOwWFPQLIo6FU/F++N/B9Rs5JsnYQ=
    HASH 计算之后
    正在排队处理的任务数:0
*/

上个例子的 Promise 版本

'use strict';

var path = require('path');
var fs = require('fs');
var assert = require('assert');
var Thread = require('node-threadobject');
const Promise = require('bluebird');
const co = Promise.coroutine;

var thread = new Thread();
thread.set_encode('base64');

fs.readFile('./test/thread.js', function(err, data) {
  co(function*(){
    var r = yield thread.sha2({data, type: 256});
    console.log(r);
  })();
});

/*
  result:
    drK1C69gYX9I8qYOwWFPQLIo6FU/F++N/B9Rs5JsnYQ=
*/

消息认证码(HMAC)

/*
 see test/example/hmac.js
*/
'use strict';
var path = require('path');
var fs = require('fs');
var assert = require('assert');
var Thread = require('node-threadobject');
var crypto = require('crypto');
var thread = new Thread();
var key = '_random_key_';

fs.readFile('test/thread.js', function(err, data) {
  thread.hmac({data, type: 512, key}, function(err, data){
    if(err) return console.error(err);
    console.log(data);
  });
  var hmac = crypto.createHmac('sha512', key);
  hmac.update(data);
  console.log(hmac.digest('hex'));
});

/*
result:
    9c2e2ddd685c05ddfdcc9f92194cb1308b17260ad09b12e259b1d8c4c3b61881b9faa10891f28f718a502347815d795793318c094edb504c5ac19ca0f5521895
    9c2e2ddd685c05ddfdcc9f92194cb1308b17260ad09b12e259b1d8c4c3b61881b9faa10891f28f718a502347815d795793318c094edb504c5ac19ca0f5521895
*/

Ed25519签名(EdDSA)

/*
see test/ed25519.js
*/

'use strict';
const Thread = require('node-threadobject');
var thread = new Thread();

thread.sign(new Buffer('a message'),'af9881fe34edfd3463cf3e14e22ad95a0608967e084d3ca1fc57be023040de59', function(err, data){
  console.log(data.toString('hex'));
});

/*
result:
    1b7b8d7141a2fd9e1fc99175eaa8dbcf82189d007a4210fc58f0cf24b5e0cc6d4f8b138352953a97d4237a9a75bfce97f5b12f7a8e56692ee7aafd61161f8204
*/

使用 V8 虚拟机运行一段 Js 代码

'use strict';
const Thread = require('node-threadobject');
var assert = require('assert');

var thread = new Thread();

var codeMain = `
function main(v){
	v = JSON.parse(v);
  return v.a + v.b;
}
`;

thread.runCode(codeMain, JSON.stringify({
        a: 5,
        b: 100
      }), function(err, res){
        assert.ifError(err);
        console.log(res);
});

/*
result:

105
*/

压力测试 (Pressure test report)

/*
 see pressure-test/mem-pressure-test.js
*/
'use strict';

var fs = require('fs');
var Thread = require('node-threadobject');
var thread = new Thread();
thread.set_encode('base64');

var fData = null;
function callback(err, data) {
  if(err) return console.error(err);
  console.log(data);
  setImmediate(function(){
    thread.sha2({data: fData, type: 256}, callback);
  });
}
fs.readFile('./mem-pressure-test', function(err, data){
  fData = data
  thread.sha2({data: fData, type: 256}, callback);
});

On Win 7 x86-64bit & node-v8.1.0

After 30 mins of running, mem usage maintained at ~16M

Benchmarks

多核电脑上,计算一个大文件的消息认证码,总计算量一致时,使用 threadobject 创建两个线程可以使得时间节约 50%

// benchmarks/slow.js 只使用一个线程计算
const thread = new Thread();
var r = yield Promise.all([
        thread.hmac({data, type: 384, key}),
        thread.hmac({data, type: 512, key})
      ]);

// benchmarks/fast.js 委托给两个线程分别计算
const thread1 = new Thread();
const thread2 = new Thread();
var r = yield Promise.all([
        thread1.hmac({data, type: 384, key}),
        thread2.hmac({data, type: 512, key})
      ]);

已包含的方法 (APIs)

close  //同步的关闭线程
isRunning  //返回线程对象的线程是否运行(存在)
delayByMil  //以毫秒延迟
delayBySec  //
delayByMin  //
delayByHour  //
initPrint  //初始化一个打印任务
printLog  //顺序打印
closeLog  //关闭打印
sha2  //SHA {256, 384, 512}
hmac  // {256, 384, 512}
numOfTasks  //线程队列里CPU密集型任务个数
makeKeypair // 使用 Ed25519 生成密钥对
sign // 使用 Ed25519 签名 Ed25519-DSA
verify // Ed25519 验证
runCode //使用 V8 虚拟机运行 js

Other example

// see test/

More descriptions

https://github.com/dazoe/ed25519.git (Ed25519 implementation)

证书 (License)

BSD