我没有看到任何内容JavaScript 规范 https://tc39.github.io/ecma262/, the 提议的 DOM 规范扩展 http://tc39.github.io/ecmascript_sharedmem/dom_shmem.html相关SharedArrayBuffer
, 或者当前 WHAT-WG HTML 规范 https://html.spec.whatwg.org/表明当一个线程将消息发送给另一个线程并且另一个线程处理该消息时,共享内存将跨线程同步/更新。 (After一个已经将共享内存发送给另一个。)但是,我也无法通过实验验证它doesn't发生(在我的测试中,我没有看到过时的值)。我是否缺少这样的保证?如果有,保证在哪里?例如,它是否记录在案postMessage
我错过了它,或者是否有一些关于返回到保证它的事件循环/作业队列的东西(因为处理来自另一个线程的消息涉及这样做)等等?或者,这绝对是not有保证(并且该信息在某个规范中)?
Please不要推测或做出“合理的猜测”。我正在寻找硬信息:来自规范来源的引用,一个可复制的实验,表明它不能得到保证(尽管我想这是否只是一个实现错误的问题),诸如此类的事情。
以下是我的测试的来源,尚未能够捕获不同步的内存。要运行它,您需要使用当前支持的浏览器SharedArrayBuffer
,我认为目前意味着 Chrome v67 或更高版本(Firefox、Edge 和 Safari 都支持,但在 2018 年 1 月因 Spectre 和 Meltdown 事件而禁用了它;Chrome 也支持了,但在 v67 中重新启用了它 [2018 年 7 月]在启用了站点隔离功能的平台上)。
sync-test-postMessage.html
:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Sync Test postMessage</title>
</head>
<body>
<script src="sync-test-postMessage-main.js"></script>
</body>
</html>
sync-test-postMessage-main.js
:
const array = new Uint32Array(new SharedArrayBuffer(Uint32Array.BYTES_PER_ELEMENT));
const worker = new Worker("./sync-test-postMessage-worker.js");
let counter = 0;
const limit = 1000000;
const report = Math.floor(limit / 10);
let mismatches = 0;
const now = performance.now();
const log = msg => {
console.log(`${msg} - ${mismatches} mismatch(es) - ${performance.now() - now}ms`);
};
worker.addEventListener("message", e => {
if (e.data && e.data.type === "ping") {
++counter;
const value = array[0];
if (counter !== value) {
++mismatches;
console.log(`Out of sync! ${counter} !== ${value}`);
}
if (counter % report === 0) {
log(`${counter} of ${limit}`);
}
if (counter < limit) {
worker.postMessage({type: "pong"});
} else {
console.log("done");
}
}
});
worker.postMessage({type: "init", array});
console.log(`running to ${limit}`);
sync-test-postMessage-worker.js
:
let array;
this.addEventListener("message", e => {
if (e.data) {
switch (e.data.type) {
case "init":
array = e.data.array;
// fall through to "pong"
case "pong":
++array[0];
this.postMessage({type: "ping"});
break;
}
}
});
使用该代码,如果内存未同步,我希望主线程在某个时刻看到共享数组中的陈旧值。但在我看来,这段代码完全有可能只是happens由于消息传递涉及的时间尺度相对较大......