2014-12-06 160 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