2014-12-06 141 views
1

我有一个Greasemonkey脚本,在任务队列上运行。该队列是一串串行化的JSON对象,分散在脚本个人偏好空间中,以GM_getValue,GM_setValueGM_listValues访问。同步Greasemonkey脚本的多个实例

我想使这个脚本同时运行(相同的机器,相同的浏览器,不同的标签),同时仍然保持共享队列。我知道Javascript主要运行在一个单独的线程中(Web Workers除外),但是我认为在单独的选项卡中打开的页面不是这种情况,所以它必须同时运行。

在这种情况下,我该如何正确组织共享访问这样的对象,以防止竞争条件?比赛条件会出现吗?

回答

0

让我惊讶的是,似乎没有竞争条件,因为Javascript运行在单线程整个浏览器。我曾与以下userscript测试它:

// ==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; 
} 

随着大BLOCK值,浏览器似乎大多是反应迟钝,无论标签或窗口违规脚本在运行,其中

所以,同步脚本,它是足以保持一些共享的标志告诉结构已被使用,并且随机间隔轮询使其变为空闲(简单的方法,但可以饿死),或者使用广播并维持待获得的“互斥体”队列, ,实现一个监视器(有点,因为每个脚本调用都在关键部分)。

+0

为了测试竞态条件,2个线程应该试图修改同一个变量,这是你在这里没有做的。 – Dalius 2016-05-29 11:46:01