我什么也没看到
the JavaScript spec
,的
proposed DOM spec extensions
SharedArrayBuffer
current WHAT-WG HTML spec
当一个线程向另一个线程发布消息而另一个线程处理消息时,建议跨线程同步/更新共享内存(
之后
一个已经将共享内存发送给另一个了。)但是,我也无法通过实验验证它
发生(在我的测试中,我没有看到过时的值)。有没有这样的保证,我失踪了,如果是的话,在哪里保证?例如,是否记录了
postMessage
我已经错过了它,或者是否有什么关于退回到事件循环/作业队列来保证它(因为处理来自另一个线程的消息需要这样做),等等。?或者说,这是肯定的吗
不
保证(信息在某个地方的规范中)?
拜托
不要猜测或做出“合理的猜测”。我在寻找硬信息:来自规范来源的引文,一个可复制的实验,它表明这是不能保证的(尽管我认为这是一个是否只是实现错误的问题),诸如此类的东西。
下面是我的测试的源代码,这些测试还不能捕获不同步的内存。要运行它,您需要使用当前支持的浏览器
,我认为目前这意味着Chromev67或更高版本(Firefox、Edge和Safari都支持Chromev67,但在2018年1月因幽灵和熔毁而禁用了Chromev67;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;
}
}
});
使用该代码,如果内存没有同步,我希望在某个时候主线程在共享数组中看到一个过时的值。但很可能(在我看来)这段代码
发生
因为消息传递涉及的时间尺度相对较大。。。