Javascript 同步同一Greasemonkey脚本的多个实例
我有一个Greasemonkey用户脚本,它在任务队列上运行。这个队列是一组序列化的JSON对象,分散在脚本私有首选项空间中,可以使用Javascript 同步同一Greasemonkey脚本的多个实例,javascript,multithreading,greasemonkey,Javascript,Multithreading,Greasemonkey,我有一个Greasemonkey用户脚本,它在任务队列上运行。这个队列是一组序列化的JSON对象,分散在脚本私有首选项空间中,可以使用GM_getValue、GM_setValue和GM_listValues访问 我想让这个脚本同时运行(相同的机器、相同的浏览器、不同的选项卡),同时保持共享队列。我知道Javascript主要在一个线程中运行(Web Workers除外),但我认为在单独的选项卡中打开的页面不是这种情况,因此它必须同时运行 在这种情况下,如何正确地组织对此类对象的共享访问,以防止
GM_getValue
、GM_setValue
和GM_listValues
访问
我想让这个脚本同时运行(相同的机器、相同的浏览器、不同的选项卡),同时保持共享队列。我知道Javascript主要在一个线程中运行(Web Workers除外),但我认为在单独的选项卡中打开的页面不是这种情况,因此它必须同时运行
在这种情况下,如何正确地组织对此类对象的共享访问,以防止竞争条件?是否会出现竞态条件?令我惊讶的是,似乎没有竞态条件,因为Javascript在整个浏览器中是单线程运行的。我已使用以下用户脚本对其进行了测试:
// ==UserScript==
// @name test-concurrency
// @namespace mw.tools
// @include /^http://localhost//
// @version 1
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
var BLOCK = 1000;
var ATOM = 'foo';
switch (window.location.search) {
case '?inc':
setInterval(function() {
var i;
for (i = 0; i < BLOCK; i++) {
GM_setValue(ATOM, GM_getValue(ATOM, 0) + 1);
}
document.title = '' + GM_getValue(ATOM, 0) + ' || ' + (GM_getValue(ATOM, 0) % BLOCK);
}, 1);
break;
case '?ver':
setInterval(function() {
var v;
var v0;
v0 = GM_getValue(ATOM);
for (i = 0; i < BLOCK; i++) {
v = GM_getValue(ATOM);
if (v != v0) {
document.title = v0 + ' || broken';
alert('BORKEH!!1111oneone');
}
}
document.title = v0;
}, 1);
break;
}
/==UserScript==
//@name测试并发性
//@mw.tools
//@包括/^http://localhost//
//@version 1
//@grant GM_getValue
//@grant GM_setValue
//==/UserScript==
var块=1000;
var ATOM='foo';
开关(窗口.位置.搜索){
案例公司:
setInterval(函数(){
var i;
对于(i=0;i
对于较大的块
值,无论在哪个选项卡或窗口中运行有问题的脚本,浏览器似乎大多没有响应
因此,对于同步脚本,只需保持一些共享的标志通知结构已经在使用,并进行随机间隔轮询使其变为自由(简单的方法,但可能会饿死),或者使用
postWindow()
广播并维护那些想要获取“互斥体”的人的挂起队列,实现一个监视器(有点像,因为每个脚本调用都在一个关键部分)。要测试竞争条件,两个线程应该尝试修改同一个变量,而您在这里没有这样做。@Dalius这是不正确的。一个线程写入变量,另一个线程从中读取就足以创建竞争条件。