2014-12-06 7 views
1

나는 작업 대기열에서 작동하는 Greasemonkey 사용자 스크립트를 가지고 있습니다. 이 대기열은 GM_getValue, GM_setValueGM_listValues으로 액세스 할 수 있도록 스크립트 개인 환경 설정 공간에 분산되어있는 직렬화 된 JSON 객체의 묶음입니다.동일한 Greasemonkey 스크립트의 여러 인스턴스 동기화

공유 대기열을 유지하면서이 스크립트를 동시에 (동일한 컴퓨터, 동일한 브라우저, 다른 탭) 실행하고 싶습니다. Javascript는 대부분 웹 작업자를 제외한 단일 스레드에서 실행됩니다. 그러나 별도의 탭에서 열린 페이지에는 그렇지 않으므로 동시에 실행해야합니다.

이 경우 경쟁 조건을 방지하기 위해 이러한 개체에 대한 공유 액세스를 어떻게 올바르게 구성 할 수 있습니까? 경주 조건이 전혀 나타나지 않습니까?

답변

0

자바가 하나의 스레드에서 실행되기 때문에 내 놀랍게도 많은 경쟁 조건이있는 것 같습니다. 전체 브라우저. 나는 다음과 같은 userscript으로 테스트했다 :. 큰 BLOCK 값으로

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

, 브라우저에 관계없이 탭이나 창에 잘못된 스크립트가 실행되는의 대부분이 응답하지 않는 것으로 보인다

을 그래서, 스크립트를 동기화, 그건 구조체가 이미 사용 중임을 나타내는 공유 플래그를 유지하고, 임의의 간격 폴링을 사용하여 무료 (쉬운 방법이지만 굶어 죽을 수 있음)하거나, "mutex"를 획득하려는 사람들의 대기열을 보류하고 유지 관리하는 데 충분합니다. 각 스크립트 호출이 중요한 섹션에 있기 때문에 일종의 모니터를 구현합니다.

+0

경쟁 조건을 테스트하려면 2 개의 스레드가 여기에서 수행하지 않는 동일한 변수를 수정해야합니다. – Dalius

관련 문제