क्या जावास्क्रिप्ट में म्यूटेक्स की आवश्यकता है?


104

मैंने इस लिंक को देखा है: जावास्क्रिप्ट में पारस्परिक बहिष्करण को लागू करना । दूसरी ओर, मैंने पढ़ा है कि जावास्क्रिप्ट में कोई सूत्र नहीं हैं, लेकिन वास्तव में इसका क्या मतलब है?

जब घटनाएँ होती हैं, तो कोड में वे कहाँ रुकावट डाल सकते हैं?

और यदि जेएस में कोई सूत्र नहीं हैं, तो क्या मुझे जेएस में म्यूटेक्स का उपयोग करने की आवश्यकता है या नहीं?

विशेष रूप से, मैं कार्यों से बुलाया का उपयोग कर के प्रभाव के बारे में सोच रहा हूँ setTimeout()और XmlHttpRequest's onreadystatechangeविश्व स्तर पर सुलभ चर पर।


1
नहीं, कोई म्यूटेक्स या जावास्क्रिप्ट में कोई अन्य संगामिति नियंत्रण उपकरण नहीं। देखें कि जावास्क्रिप्ट में कोई कंसीलर कंट्रोल टूल क्यों नहीं है
उज़ैर फारूक

जवाबों:


101

जावास्क्रिप्ट को एक रीएन्ट्रेंट भाषा के रूप में परिभाषित किया गया है जिसका अर्थ है कि उपयोगकर्ता के सामने कोई थ्रेडिंग नहीं है, कार्यान्वयन में थ्रेड्स हो सकते हैं। setTimeout()स्क्रिप्ट और अतुल्यकालिक कॉलबैक जैसे कार्यों को चलाने में सक्षम होने से पहले स्क्रिप्ट इंजन के सोने के लिए प्रतीक्षा करने की आवश्यकता होती है।

इसका मतलब है कि किसी घटना में होने वाली हर चीज को अगले कार्यक्रम के संसाधित होने से पहले पूरा किया जाना चाहिए।

कहा जा रहा है, आपको एक म्यूटेक्स की आवश्यकता हो सकती है यदि आपका कोड ऐसा कुछ करता है जहां यह उम्मीद करता है कि जब अतुल्यकालिक घटना को निकाल दिया गया था और कॉलबैक कहा गया था, तो इसके बीच कोई बदलाव नहीं होगा।

उदाहरण के लिए यदि आपके पास एक डेटा संरचना है जहां आप एक बटन क्लिक करते हैं और यह एक XmlHttpRequest भेजता है जो कॉलबैक को डेटा संरचना को विनाशकारी तरीके से बदलता है, और आपके पास एक और बटन है जो उसी डेटा संरचना को सीधे बदलता है, जब घटना थी निकाल दिया गया और जब कॉल बैक निष्पादित किया गया तो उपयोगकर्ता कॉलबैक से पहले डेटा संरचना को क्लिक और अपडेट कर सकता था जो तब मूल्य खो सकता था।

यद्यपि आप एक दौड़ की स्थिति बना सकते हैं जैसे कि आपके कोड में इसे रोकना बहुत आसान है क्योंकि प्रत्येक फ़ंक्शन परमाणु होगा। यह बहुत काम होगा और वास्तव में दौड़ की स्थिति बनाने के लिए कुछ विषम कोडिंग पैटर्न लेगा।


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

19

इस प्रश्न के उत्तर थोड़े पुराने हैं, हालांकि उस समय सही थे जब वे दिए गए थे। और अभी भी सही है अगर एक क्लाइंट-साइड जावास्क्रिप्ट एप्लिकेशन को देख रहा है जो वेबवर्क का उपयोग नहीं करता है।

वेब-वर्कर्स पर लेख:
वेबवर्कर्स पर वेबवर्कर्स मोज़िला का उपयोग करके जावास्क्रिप्ट में मल्टीथ्रेडिंग

यह स्पष्ट रूप से दर्शाता है कि वेब-वर्कर्स के माध्यम से जावास्क्रिप्ट में मल्टीथ्रेडिंग क्षमताएं हैं। प्रश्न के विषय में जावास्क्रिप्ट में म्यूटेक्स की आवश्यकता होती है? मैं इस बारे में अनिश्चित हूं। लेकिन यह स्टैकओवरफ़्लो पोस्ट प्रासंगिक लगता है:
एन एसिंक्रोनस थ्रेड्स के लिए म्यूचुअल बहिष्करण


3
अतीत से विस्फोट, लेकिन मैं mutexes के लिए की जरूरत है जब कई टैब एक ही स्थानीय संग्रहण तक पहुंचने का सामना करना पड़ा
PSP

3
WebWorkers फिर से प्रवेश को प्रभावित नहीं करते हैं क्योंकि वे कोई चर स्थिति साझा नहीं करते हैं और केवल संदेशों को पारित करके मुख्य थ्रेड के साथ संवाद करते हैं, जो घटनाओं को ट्रिगर करते हैं।
अलनीतक

9

@William बताते हैं,

आपको एक म्यूटेक्स की आवश्यकता हो सकती है यदि आपका कोड कुछ ऐसा करता है जहां यह उम्मीद करता है कि जब अतुल्यकालिक घटना को निकाल दिया गया था और जब कॉलबैक कहा गया था, तो इसके बीच कोई बदलाव नहीं होगा।

इसे और अधिक सामान्यीकृत किया जा सकता है - यदि आपका कोड कुछ ऐसा करता है जहां उसे संसाधन के अनन्य नियंत्रण की उम्मीद है जब तक कि एक अतुल्यकालिक अनुरोध का समाधान नहीं हो जाता है, तो आपको म्यूटेक्स की आवश्यकता हो सकती है।

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

var save_lock = false;
$('#save_button').click(function(){
    if(!save_lock){
        //lock
        save_lock=true;
        $.ajax({
            success:function()
                //unlock
                save_lock = false;  
            }
        });
    }
}

मुझे यकीन नहीं है कि अगर यह सबसे अच्छा तरीका है और मुझे यह देखने में दिलचस्पी होगी कि दूसरों को जावास्क्रिप्ट में पारस्परिक बहिष्करण कैसे संभालना है, लेकिन जहां तक ​​मुझे पता है कि यह एक सरल म्यूटेक्स है और यह आसान है।


4
मैं शायद ही इसे म्यूटेक्स कहूंगा, कम से कम पारंपरिक अर्थों में नहीं, क्योंकि आपके पास किसी भी समय एक ही ब्लॉक के संदर्भ में दो धागे नहीं हैं।
ओवेश

10
एक म्यूटेक्स केवल एक एल्गोरिथ्म है जो 'सामान्य संसाधन के युगपत उपयोग से बचने में मदद करता है'। यद्यपि मल्टीथ्रेडिंग म्यूटेक्स की आवश्यकता पैदा करता है, लेकिन परिभाषा में ऐसा कुछ भी नहीं है जो कहता है कि एक म्यूटेक्स आपके द्वारा वर्णित स्थिति के लिए विशिष्ट है।
अल्ज़क्लेर्क

1
आप म्यूटेक्स की औपचारिक परिभाषा के बारे में सही हैं। लेकिन शायद ही ऐसा हो जब लोग वास्तविक दुनिया में म्यूटेक्स के बारे में बात करते हैं।
ओवेश

यह अपेक्षा के अनुरूप काम नहीं कर रहा है। दुर्भाग्य से, बार-बार किए गए क्लिक अभी भी ajax कॉल को आग लगा देंगे। कोई अन्य विचार?
मोहम्मद शरीफ C

1
यकीन है कि यह एक में लपेटा जाना चाहिए whileसाथ setTimeoutया एक setIntervalसाथ clearIntervalताकि आप फिर से प्रयास करें और समय समाप्ति तर्क है कि n विफलताओं के बाद। के रूप में छोड़ने का मतलब है कि आप बस उस कोड को बायपास करेंगे जो लॉक है। म्यूटेक्स और साझा वस्तुओं के साथ बाहरी हैंडलिंग उतना ही महत्वपूर्ण है जितना कि कार्यान्वयन स्वयं।
MrMesees

6

जावास्क्रिप्ट सिंगल थ्रेडेड है ... हालांकि क्रोम एक नया जानवर हो सकता है (मुझे लगता है कि यह भी सिंगल थ्रेडेड है, लेकिन प्रत्येक टैब का अपना जावास्क्रिप्ट धागा है ... मैंने इस पर विस्तार से गौर नहीं किया है, इसलिए मुझे उद्धृत न करें वहाँ)।

हालाँकि, एक बात जो आपको चिंता करने की ज़रूरत है कि आपका जावास्क्रिप्ट आपके द्वारा भेजे गए एक ही क्रम में वापस आने वाले कई अजाक्स अनुरोधों को कैसे हैंडल करेगा। इसलिए, आपको वास्तव में चिंता करने की ज़रूरत है सुनिश्चित करें कि आपके अजाक्स कॉल को इस तरह से संभाला जाता है कि वे प्रत्येक अभिभावक के पैरों पर कदम नहीं रखेंगे यदि परिणाम आपके द्वारा भेजे गए से अलग क्रम में वापस आते हैं।

यह टाइमआउट के लिए भी जाता है ...

जब जावास्क्रिप्ट बढ़ता है, तो शायद म्यूटेक्स और इस तरह की चिंता करें ...।


4

जब संसाधन है कि टैब / विंडो के बीच साझा कर रहे हैं, उन तक पहुंचने की तरह हाँ, mutexes जावास्क्रिप्ट की आवश्यकता हो सकती है localStorage

उदाहरण के लिए, यदि किसी उपयोगकर्ता के दो टैब खुले हैं, तो निम्न जैसा सरल कोड असुरक्षित है:

function appendToList(item) {
    var list = localStorage["myKey"];
    if (list) {
        list += "," + item;
    }
    else {
        list = item;
    }
    localStorage["myKey"] = list;
}

उस समय के बीच जब लोकलस्टोरेज आइटम 'गेट' और 'सेट' हो जाता है, दूसरा टैब वैल्यू को संशोधित कर सकता है। यह आम तौर पर संभव नहीं है, लेकिन संभव है - आपको अपने विशेष परिस्थितियों में किसी भी विवाद के साथ जुड़े संभावना और जोखिम के लिए खुद को आंकने की आवश्यकता होगी।

अधिक विस्तार के लिए निम्नलिखित लेख देखें:


2

जावास्क्रिप्ट, भाषा , आप जितना चाहें उतना मल्टीथ्रेडेड हो सकते हैं, लेकिन जावास्क्रिप्ट इंजन के ब्राउज़र एम्बेडिंग केवल एक बार (प्रति टैब, वर्तमान में) एक कॉलबैक (ऑनलोड, ऑनफोकस, <स्क्रिप्ट>, आदि ...) चलाता है। पंजीकरण और कॉलबैक प्राप्त करने के बीच परिवर्तनों के लिए एक म्यूटेक्स का उपयोग करने के विलियम के सुझाव को इस वजह से बहुत शाब्दिक रूप से नहीं लिया जाना चाहिए, क्योंकि आप कॉलबैक के बाद से कॉलबैक में हस्तक्षेप नहीं करना चाहते हैं जो अनलॉक हो जाएगा और वर्तमान बैकबैक के पीछे अवरुद्ध हो जाएगा। ! (वाह, अंग्रेजी थ्रेडिंग के बारे में बात करने के लिए बेकार है।) इस मामले में, आप शायद वर्तमान घटना को फिर से जाँचने की तर्ज पर कुछ करना चाहते हैं यदि कोई ध्वज सेट किया जाता है, या तो सचमुच या सेटटाइमआउट की पसंद के साथ ()।

यदि आप JS के एक अलग एम्बेडिंग का उपयोग कर रहे हैं, और जो एक ही बार में कई थ्रेड निष्पादित करता है, तो यह थोड़ा अधिक पासा हो सकता है, लेकिन जिस तरह से JS आसानी से कॉलबैक का उपयोग कर सकता है और संपत्ति के उपयोग पर वस्तुओं को लॉक करता है, स्पष्ट लॉकिंग लगभग आवश्यक नहीं है। । हालांकि, मुझे आश्चर्य होगा कि अगर मल्टी कोडिंग का इस्तेमाल करने वाले सामान्य कोड (जैसे, गेम स्क्रिप्टिंग) के लिए डिज़ाइन किया गया एम्बेडिंग कुछ स्पष्ट लॉकिंग आदिम भी नहीं देता है।

पाठ की दीवार के लिए क्षमा करें!


0

घटनाओं का संकेत दिया जाता है, लेकिन जावास्क्रिप्ट निष्पादन अभी भी एकल-थ्रेडेड है।

मेरी समझ यह है कि जब घटना का संकेत दिया जाता है तो इंजन बंद हो जाता है जो इवेंट हैंडलर को चलाने के लिए इस समय निष्पादित होता है। हैंडलर समाप्त होने के बाद, स्क्रिप्ट निष्पादन फिर से शुरू हो जाता है। अगर इवेंट हैंडलर ने कुछ साझा चर को बदल दिया तो फिर से शुरू किया गया कोड इन परिवर्तनों को "नीले रंग से बाहर" दिखाई देगा।

यदि आप साझा किए गए डेटा को "सुरक्षित" करना चाहते हैं, तो साधारण बूलियन ध्वज पर्याप्त होना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.