2009-02-17 4 views
43

वहाँ एक परमाणु परीक्षण और सेट, सेमाफोर, या Javascript में ताला के रूप में ऐसी बात है?जावास्क्रिप्ट सेमफोर/टेस्ट-एंड-सेट/लॉक?

मैं एक कस्टम प्रोटोकॉल के माध्यम से जावास्क्रिप्ट लागू async पृष्ठभूमि प्रक्रियाओं है (पृष्ठभूमि प्रक्रिया सचमुच, एक अलग प्रक्रिया में चलता ब्राउज़र से संबंधित नहीं)। मेरा मानना ​​है कि मैं दौड़ की स्थिति में दौड़ रहा हूं; बैकग्राउंड प्रक्रिया जावास्क्रिप्ट पक्ष पर चीजों को खराब करने, मेरे परीक्षण और मेरे सेट के बीच लौटती है। मुझे इसे एक वास्तविक सेमफोर बनाने के लिए एक परीक्षण-और-सेट ऑपरेशन की आवश्यकता है।

यहाँ जावास्क्रिप्ट कोड है कि पृष्ठभूमि प्रक्रियाओं का पता लगाने और उन्हें कतार के लिए प्रयास करता है:

Call = function() { 

var isRunning = true, 
    queue = []; 

return { 
    // myPublicProperty: "something", 

    call: function (method) { 
      if (isRunning) { 
       console.log("Busy, pushing " + method); 
       queue.push(method); 
      } else { 
       isRunning = true; 
       objccall(method); 
      } 
     }, 

     done: function() { 
      isRunning = false; 
      if (queue.length > 0) { 
       Call.call(queue.shift()); 
      } 
     } 
    }; 
}(); 

कॉल एक सिंगलटन कि कतार लागू करता है; कोई भी जो बाहरी प्रक्रिया का आह्वान करना चाहता है Call.call ("कुछ") करता है।

कोई भी विचार?

+0

आप यह निर्दिष्ट करना चाहते हैं कि आपकी 'प्रक्रिया' अधिक विस्तृत में क्या है। क्या यह सर्वर-साइड जावास्क्रिप्ट है? –

+2

जावास्क्रिप्ट कोड हमेशा परमाणु है, इसलिए लॉक या कुछ भी करने की आवश्यकता नहीं है। देखें [जावास्क्रिप्ट में हमारे पास एक समवर्ती नियंत्रण उपकरण क्यों नहीं है?] (Http://uzairfarooq.github.io/why-no-concurrency-control-tool-in-javascript/)। –

उत्तर

2

शायद तुम एक बुनियादी पूर्णांक सेमाफोर को लागू कर सकता है, सिर्फ डोम और लॉक में चर जोड़ने/इसे अनलॉक और सुनिश्चित करें कि आपके कार्यों यह जांच करते रहें, और उन्हें समय-समाप्त कर =)

आप उपयोग कर रहे हैं एक रूपरेखा इस तरह के Mootools के रूप में आप ऐप के प्रवाह को संभालने की कोशिश कर सकते हैं जैसे कि कॉम्पलेट और इसी तरह। क्योंकि जे एस एक बहु लड़ी भाषा नहीं है

18

जावास्क्रिप्ट कोई ताला अर्थ विज्ञान है। एकाधिक धागे केवल पूरी तरह से अलग संदर्भों में समवर्ती रूप से संचालित हो सकते हैं - उदाहरण के लिए। एचटीएमएल 5 वर्कर थ्रेड्स, या जावास्क्रिप्टकोर एपीआई के संदर्भ ऑब्जेक्ट के कई उदाहरणों की तरह चीजों में (मुझे लगता है कि स्पाइडरमोन्की की एक समान अवधारणा है)। वे साझा राज्य नहीं कर सकते हैं, इसलिए संक्षेप में सभी निष्पादन परमाणु है।

External Process: 
<JSObject>.isRunning = true; 
doSomething() 
<JSObject>.done() 

या कुछ इस तरह के (उचित API का उपयोग करके):

ठीक है, के रूप में अब आप अपने कोड के कुछ प्रदान की है मैं तुम्हें करने के लिए कुछ समान है मान लेते हैं। ऐसी स्थिति में मैं जे एस इंजन अगर जे एस अपने js वस्तु (जो JavaScriptCore क्या करेंगे) के संदर्भ में निष्पादित हो रहा है में नाकाम रहने कि आप शायद js निष्पादन के आसपास जगह में एक मैनुअल ताला लगाना करने की आवश्यकता होगी ब्लॉक करने के लिए, उम्मीद करेंगे।

क्या इंजन आप यह सब करने के लिए प्रयोग कर रहे हैं? मैं पूछता हूं क्योंकि आपके विवरण के आधार पर ऐसा लगता है कि आप उस भाषा द्वारा प्रदान किए गए सी/सी ++ एपीआई का उपयोग करते हुए एक गैर-जेएस भाषा से द्वितीयक थ्रेड से ध्वज सेट कर रहे हैं, और अधिकांश जेएस इंजन मानते हैं कि API के माध्यम से किए गए किसी भी राज्य में हेरफेर एक धागे पर हो रहा है, आमतौर पर एक ही थ्रेड जो सभी निष्पादन पर होता है।

+0

मैंने इसे थोड़ा और स्पष्ट करने के लिए उपरोक्त पूर्ण कोड जोड़ा। इंजन वेबकिट (सफारी) है। जावास्क्रिप्ट से मैं बाहरी प्रक्रियाओं का आह्वान करता हूं, और बाहरी प्रक्रिया "पूर्ण" विधि को लागू होने पर आमंत्रित करती है। असल में मुझे यह सुनिश्चित करने की ज़रूरत है कि एक समय में केवल एक बाहरी प्रक्रिया चलती है। – Parand

+0

मान लीजिए कि आप कुछ [कुछ ऑब्जेक्ट कॉल] या JSObjectCallAsFunction (संदर्भ, किया गया कार्य, कुछ ऑब्जेक्ट) के समान कुछ कर रहे हैं, आपको यह सुनिश्चित करना चाहिए कि आप मुख्य थ्रेड पर कॉल कर रहे हैं, खासकर यदि आप वेबकिट द्वारा प्रदान किए गए ओबीजेसी जेएस एपीआई का उपयोग कर रहे हैं (आईआईआरसी यह कुछ ताले को बाधित कर सकता है) – olliej

+0

क्या आपने किसी भी मौके पर आईफोन पर वेबकिट एसडीके का इस्तेमाल किया है? मैं एक साधारण खिड़की का उपयोग कर रहा हूं। स्थान योजना, एसडीके की कोशिश नहीं की है। एसडीके के बारे में और जानना अच्छा लगेगा। – Parand

0

मुझे लगता है मैं यह इतना बंद किया जा करने के लिए मैं कुछ इस तरह किया था की जरूरत ajax सामान जो चयन सूचियों भरता है,। मुझे लगता है कि आप डिफर्ड और पाइप या कुछ का उपयोग करते हुए शायद इसे सरल बना सकते हैं।

var semaphore=[]; 

function myFunc(arg){ 
    var dfd; 
    $.when(semaphore[table]).done(
     function(){ 
      dfd=myFuncInner(arg); 
     } 
    ); 
return dfd; 
} 

function myFuncInner(table){ 
semaphore[arg] = new $.Deferred(); 
... 
somethingasynchronous({ 
    semaphore[arg].resolve(); 
}); 

return semaphore[arg]; 
} 
0

सबसे पहले, जबकि यह सच है कि JavaScript को एक लड़ी है, यह सच नहीं है कि कोई क्रमबद्धता तंत्र कभी एक जावास्क्रिप्ट आवेदन के लिए आवश्यक है।

एक साधारण उदाहरण है, जब सबमिट बटन को एक निश्चित समय के लिए फीका जाना चाहिए जिसके दौरान सर्वर पर एक अजाक्स अनुरोध काम कर रहा है। जब एसिंक्रोनस अजाक्स अनुरोध सफलतापूर्वक पूरा हो जाता है तो एक संदेश दिखाना चाहिए जहां बटन होता था।

हालांकि बटन के फीडआउट को रद्द करने में सक्षम होना अच्छा होगा और जल्द ही अजाक्स अनुरोध पूरा होने पर अपनी शैली को "डिस्प्ले: कोई नहीं" पर सेट करना अच्छा होगा, यह jQuery में संभव नहीं है। इसके अलावा, एक समाधान घटनाओं का उपयोग दो एक साथ गतिविधियों को सिंक्रनाइज़ करने के लिए कर सकता है, लेकिन यह अनिवार्य रूप से एक साधारण समस्या के लिए ओवरकिल है।

एक कम तकनीक समाधान लॉक को मतदान करना है और जब फेडआउट पूर्ण हो जाता है तो अनलॉक किया जाता है लेकिन "सर्वर किया गया" संदेश सफलता कॉलबैक तक प्रदर्शित नहीं होता है, जैसा कि $ .post द्वारा निर्धारित किया जाता है।

var gl_lock; 
var gl_selfID; 

function poll_lock(message) { 
    if (gl_lock === 0) { 
      $('#output').text(message).fadeIn(200); 
      window.clearInterval(gl_selfID); 
    } 
} // end of poll_lock 

function worker() { 

    // no one gets in or out 
    gl_lock = 1; 

    $.post(..., data,function() { 
      gl_selfID = window.setInterval(poll_lock, 40, data.message); 
     }, "json"); 

    // end of fadeout unlock the semaphore 
    $('#submit-button').fadeOut(400, function() { gl_lock = 0; }); 

    } // end of worker 

अंत में, मुझे लगता है कि यह, और अधिक विस्तृत जवाब है साथ लाइनों पहले से perrohunter द्वारा इस चर्चा में सुझाव दिया।

0

मुझे सच में यकीन नहीं है कि सवाल वास्तव में क्या पूछ रहा है, लेकिन यहां मेरी सेमफोर ऑब्जेक्ट देखें: https://github.com/agamemnus/semaphore.js