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.
支持的操作系统(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 = ;var thread = ; thread; console; /*result: thread running state: true after two secs thread running state: false*/
在另一个线程中计算一个文件的 HASH 值
/* see test/example/sha2.js*/'use strict'; var path = ;var fs = ;var assert = ;var Thread = ;var thread = ;thread; console;fs; /*result: HASH 计算之前 正在排队处理的任务数:1 HASH 计算结果 drK1C69gYX9I8qYOwWFPQLIo6FU/F++N/B9Rs5JsnYQ= HASH 计算之后 正在排队处理的任务数:0*/
上个例子的 Promise 版本
'use strict'; var path = ;var fs = ;var assert = ;var Thread = ;const Promise = ;const co = Promisecoroutine; var thread = ;thread; fs; /* result: drK1C69gYX9I8qYOwWFPQLIo6FU/F++N/B9Rs5JsnYQ=*/
消息认证码(HMAC)
/* see test/example/hmac.js*/'use strict';var path = ;var fs = ;var assert = ;var Thread = ;var crypto = ;var thread = ;var key = '_random_key_'; fs; /*result: 9c2e2ddd685c05ddfdcc9f92194cb1308b17260ad09b12e259b1d8c4c3b61881b9faa10891f28f718a502347815d795793318c094edb504c5ac19ca0f5521895 9c2e2ddd685c05ddfdcc9f92194cb1308b17260ad09b12e259b1d8c4c3b61881b9faa10891f28f718a502347815d795793318c094edb504c5ac19ca0f5521895*/
Ed25519签名(EdDSA)
/*see test/ed25519.js*/ 'use strict';const Thread = ;var thread = ; thread; /*result: 1b7b8d7141a2fd9e1fc99175eaa8dbcf82189d007a4210fc58f0cf24b5e0cc6d4f8b138352953a97d4237a9a75bfce97f5b12f7a8e56692ee7aafd61161f8204*/
使用 V8 虚拟机运行一段 Js 代码
'use strict';const Thread = ;var assert = ; var thread = ; var codeMain = `function main(v){ v = JSON.parse(v); return v.a + v.b;}`; thread; /*result: 105*/
压力测试 (Pressure test report)
/* see pressure-test/mem-pressure-test.js*/'use strict'; var fs = ;var Thread = ;var thread = ;thread; var fData = null; { iferr return console; console; ;}fs;
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