Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 同步同一Greasemonkey脚本的多个实例_Javascript_Multithreading_Greasemonkey - Fatal编程技术网

Javascript 同步同一Greasemonkey脚本的多个实例

Javascript 同步同一Greasemonkey脚本的多个实例,javascript,multithreading,greasemonkey,Javascript,Multithreading,Greasemonkey,我有一个Greasemonkey用户脚本,它在任务队列上运行。这个队列是一组序列化的JSON对象,分散在脚本私有首选项空间中,可以使用GM_getValue、GM_setValue和GM_listValues访问 我想让这个脚本同时运行(相同的机器、相同的浏览器、不同的选项卡),同时保持共享队列。我知道Javascript主要在一个线程中运行(Web Workers除外),但我认为在单独的选项卡中打开的页面不是这种情况,因此它必须同时运行 在这种情况下,如何正确地组织对此类对象的共享访问,以防止

我有一个Greasemonkey用户脚本,它在任务队列上运行。这个队列是一组序列化的JSON对象,分散在脚本私有首选项空间中,可以使用
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这是不正确的。一个线程写入变量,另一个线程从中读取就足以创建竞争条件。