node 怎么实现并行化执行传输不可序列化对象?

107 天前
 nyxsonsleep

现在的需求是存在一个类内的方法,原来是串行的,现在需要改并行。现在我需要将一个对象 obj ,或者对象的方法 obj.run 传入子线程,然后回调执行。

但是我尝试了几种方式,似乎是没办法将复杂的对象进行传递?以至于常规的回调函数的方式没办法在 node 的并行化中实现。

  1. worker_thread
new Worker(moduleThreadFile, 
workerData:{'obj':obj}) //ERROR

会报告 Cannot set property code of which has only a getter.

  1. workerpool
pool=workerpool.pool()
pool.exec(obj,[])

实际上传入的 obj 在子线程中是 undefined

2695 次点击
所在节点    Node.js
51 条回复
okakuyang
107 天前
维护一个 map ,用 id 来区分哪个任务完成了,触发相应回调。
nyxsonsleep
107 天前
@okakuyang #1 能简单举例一些伪代码来做示例吗? node 用得少。
jifengg
107 天前
没用过 workerpool ,但是,以我的理解
pool.exec(obj,[])
exec 第一个参数应该是一个 function ?,第二个参数你写了空数组的[],应该是传给这个 function 的参数列表?
yaodong0126
107 天前
传不了,看文档,写的清楚的不能更清楚了,用什么工具之前多看文档,多看文档
shadowyue
107 天前
看文档,worker 能传递的数据格式有要求的
shadowyue
107 天前
nyxsonsleep
107 天前
@jifengg #3 function 也试过,没区别
nyxsonsleep
107 天前
@yaodong0126 #4 我想我需要的什么工具能支持传输完整原始对象的方法。
photon006
107 天前
bluebird.map()比较方便实现并行,还能设置并发量 concurrency

http://bluebirdjs.com/docs/api/promise.map.html
nyxsonsleep
107 天前
@shadowyue #5 这说明了 workerData 不能传输这种对象。那么有其他方法可以实现吗?
luckyscript
107 天前
workerData <any> Any JavaScript value that is cloned and made available as require('node:worker_threads').workerData. The cloning occurs as described in the HTML structured clone algorithm, and an error is thrown if the object cannot be cloned (e.g. because it contains functions).

---

一定要通过子线程的方案来实现吗?把需要执行的方法改造成异步的形式是不是也可以。
nyxsonsleep
107 天前
@luckyscript #11 这个是计算密集任务
shadowyue
107 天前
#10 @nyxsonsleep

你如果一定要传递这个对象参数,最直接的就是把这个对象,转成符合要求的数据类型。
比如把对象拍平,把值弄成数组传递
nyxsonsleep
107 天前
@photon006 #9 看起来是个异步模型。我这个可能需要的是计算密集型加速方案。
nyxsonsleep
107 天前
@shadowyue #13 无法实现,对象非常复杂。
shadowyue
107 天前
#15 对象可以序列化存储吗?可以的话直接写文件或者写数据库,worker 自己去读
photon006
107 天前
@nyxsonsleep

确实,bluebird.map()适合 io 密集型任务的并行执行,计算密集型不合适。

计算密集型需要调用 cpu 多线程,可以通过 worker_threads 实现

主线程分配任务给 worker 线程,最简单就是传递字符串

const tasks = [
`
function taskA() {
// do something
}
`
,
`
function taskB() {
// do something
}
`
]

worker 线程接收到用 eval 语法执行 taskA 、taskB ,把执行结果返回给主线程。
duowb
107 天前
xiwh
107 天前
题主的需求大概率实现不了,Node 的 Worker 是并行用多进程实现的,那哪些对象是没法序列化的?文件句柄,线程句柄,tcp/udp 连接句柄,而这些资源在进程间都是隔离的,即便是强行序列化传过去也用不了,当然 Linux 似乎有方式实现进程间资源共享,最好的方式还是支持基于内存通信的多线程的语言 go java c++等
yaodong0126
107 天前
我的天,有这么难吗,为什么一定要让线程去执行回调,线程把任务完成后通知主不可以吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1058599

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX