JavaScript的多线程技术与传统编程语言多线程技术的区别
- 由于语言机制的限制,JavaScript中的线程之间难以共享内存(可以理解为JavaScript中的变量基本存储于线程栈中),这减少线程间的并发同步的问题,保证了JS线程的安全性。
- Node.js不支持fork进程,与Unix系统调用fork()不同,child_process模块的fork()函数不会克隆当前的进程,只是单纯地创建一个node实例。
- JS线程之间的数据共享基于对象深拷贝技术,无法共享全部对象,比如函数,因此,它们之间通过事件机制传递消息。
Node
const child_process = require('child_process');
const worker = require('worker_threads');
const express = require('express');
const colors = require('colors');
const { log, table, error } = console;
if (worker.isMainThread) {
try {
main();
} catch(e) {
info(e.message);
}
} else {
try {
task();
} catch(e) {
info(e.message);
}
}
return;
// Functions
function info() {
const list = [];
[...arguments].forEach(it => {
list.push(it.toString().rainbow);
});
log(...list);
}
function main() {
const app = new express();
app.listen(8080);
app.use((req, res, next) => {
const th = new worker.Worker(__filename, {
workerData: {
msg: '您的抽奖号码为:',
},
});
info('产生工作线程', th.threadId);
th.once('message', data => {
info('工作线程', th.threadId, '计算完毕,', '主线程开始回应客户端');
res.send(data);
});
});
}
function task() {
console.time(worker.threadId);
info('工作线程', worker.threadId, '开始执行IO或CPU密集任务');
child_process.execSync('sleep 2');
worker.parentPort.postMessage([
{ index: worker.threadId, result: worker.workerData.msg + Math.round(Math.random()*100), },
]);
console.timeEnd(worker.threadId);
}
浏览器
# index.js
(function main() {
const th = new Worker('./a.js');
th.onmessage = event => {
console.log(event.data);
};
console.table(th);
})();
# a.js
postMessage({
msg: 'good',
});