0

我正在编写一个多线程程序。主线程不断接收网络数据,数据量比较大,所以使用子线程来处理数据。

接收到的数据是一个 100 字节的数据包。每次我收到一个数据包,我都会创建一个 100 字节的数据包SharedArrayBuffer并通过postMessage(). 但是主线程接收数据非常快,所以需要频繁调用postMessage通知子线程,导致CPU占用率高...影响主线程的响应速度

所以我在想,如果SharedArraybuffer可以动态增长,接收到的数据不断追加在SharedArrayBuffer的末尾,我只通知子线程一次,这样子线程也可以访问数据。

请问如何动态增加SharedArrayBuffer. 我试图以链式方式实现它,将 SharedArrayBuffer 对象存储在另一个 SharedArrayBuffer 对象中,但浏览器不允许这样做。

4

2 回答 2

0

无法调整大小,只能通过类型化数组复制。

但实际上没有分配 RAM,直到实际使用 ram。在 Node.js (v14.14.0) 下,您可以看到内存使用量如何随着缓冲区的填充而逐渐增加,或者如果使用 array.fill,它基本上是如何立即使用的。

const sharedBuffer = new SharedArrayBuffer(512 * 1024 * 1024)
const array = new Uint8Array(sharedBuffer)

// array.fill(1) // Causes ram to be allocated right away
于 2020-11-12T14:18:44.000 回答
0

请问如何动态增加SharedArrayBuffer的长度。

来自MDN 网络文档 (重点是我的)

“SharedArrayBuffer 对象用于表示一个通用的、固定长度的原始二进制数据缓冲区,类似于 ArrayBuffer 对象,但它们可用于在共享内存上创建视图。”

固定长度意味着你不能调整它的大小......所以它没有 resize() 方法也就不足为奇了。

(注意:我确实想到的一件事是,我相信 SharedArrayBuffer 有一种非常新的能力可以在 WebAssembly 中用作具有运算符的“线性内存”grow_memory。我想利用这一点将非常困难,如果完全有可能,而且如果支持的话,很多浏览器都可能不支持。)


我试图以链式方式实现它,将 SharedArrayBuffer 对象存储在另一个 SharedArrayBuffer 对象中,但浏览器不允许这样做。

没有。你只能写数字。

您似乎可以使用一个数字来索引 SharedArrayBuffers 表,并以这种方式链接它们。但是你必须担心如何在线程之间共享该表——同样的问题。

所以无论你做什么,无论哪个线程决定更新共享缓冲结构,都需要以某种方式通知其他人更新。为了使该通知能够传输 SharedArrayBuffers,它必须使用 postMessage 来执行此操作。

您是否考虑过尝试分配一个更大的 SharedArrayBuffer 开始,并将其视为循环缓冲区,以便主线程以“生产者/消费者”模式读取子线程正在执行的写入?

如果您坚持实现调整大小,您可能会考虑让缓冲区的某些部分保存一个指示它“陈旧”的指示符,并且必须从调整它大小的线程请求一个新的。您必须通过同步来控制它。如果您制作一个这样做的小样本,它可能会成为一篇很好的技术文章……如果您对小样本有疑问,这将是这里进一步提问的良好基础。

于 2018-10-10T04:14:00.843 回答