为什么我仍然可以访问缓冲区后转移到一个节点工作者?



From Node's Docs

port.postMessage(value[, transferList])(与worker.postMessage相同)

transferList可以是ArrayBuffer, MessagePort和FileHandle对象的列表。在传输之后,它们在通道的发送端将不再可用(即使它们不包含在值中)。与子进程不同,当前不支持传输句柄,如网络套接字。

"transfer"到底是什么意思?需要吗?下面的代码与我预测的不一样:

a.js

import { Worker } from "worker_threads";
import chalk from "chalk";
import { promises as fs } from "fs";
const thisChalk = chalk.blue;
const log = (s) => console.log(thisChalk`Thread A: ${s}`);
const data = await fs.readFile("./threads/test"); // buffer
const worker = new Worker("./threads/noBlock/b.js");
log(data.buffer.byteLength);
worker.postMessage(data, [data.buffer]); // data should be undefined after?
log(`post transfer > ${chalk.whiteBright(data.buffer.byteLength)}`);
worker.on("message", (message) => {
log(`B > ${message}`);
const ui8data = new Uint8Array(data);
log(ui8data);
worker.postMessage({ payload: "TERMINATE" });
});
worker.on("exit", (code) => {
log(`received termination from B w/ code > ${code}`);
log("exiting");
const ui8data = new Uint8Array(data);
log("Final data view >");
log(ui8data); // Despite having modified the buffer that was *transferred* to b and never sent back it is still usable and its contents are unmodified.
});

b.js

import { parentPort } from "worker_threads";
import chalk from "chalk";
const thisChalk = chalk.green;
const log = (s) => console.log(thisChalk`Thread B: ${s}`);
parentPort.on("message", (m) => {
if (m.payload === "TERMINATE") {
process.exit(0);
}
log(m);
m[0] = 255;
log(m); // This changes m in this context but not in a's context.
parentPort.postMessage("ping");
});

test

lorem ipusm dolor sign

运行a.js(带节点)的全输出

Thread A: 8192
Thread A: post transfer > 8192
Thread B: 108,111,114,101,109,32,105,112,117,115,109,32,100,111,108,111,114,32,115,105,103,110
Thread A: B > ping
Thread A: 108,111,114,101,109,32,105,112,117,115,109,32,100,111,108,111,114,32,115,105,103,110
Thread B: 255,111,114,101,109,32,105,112,117,115,109,32,100,111,108,111,114,32,115,105,103,110
Thread A: received termination from B w/ code > 0     
Thread A: exiting
Thread A: Final data view >
Thread A: 108,111,114,101,109,32,105,112,117,115,109,32,100,111,108,111,114,32,115,105,103,110

B中的缓冲区看起来像一个副本,因为B中的更改不会反映在a中,并且当它从未被传输回时,缓冲区仍然可以在a中访问。为什么它没有真正"转移"?数据?

文档和/或node14 LTS中transferList参数按预期工作的实现中存在错误。升级到Node 15解决了这个问题,代码正确抛出了一个错误。

相关内容

  • 没有找到相关文章

最新更新