क्या जावास्क्रिप्ट को सिंगल-थ्रेडेड होने की गारंटी है?


610

जावास्क्रिप्ट को सभी आधुनिक ब्राउज़र कार्यान्वयन में एकल-थ्रेडेड के रूप में जाना जाता है, लेकिन क्या यह किसी भी मानक में निर्दिष्ट है या यह सिर्फ परंपरा से है? क्या यह मान लेना पूरी तरह से सुरक्षित है कि जावास्क्रिप्ट हमेशा सिंगल-थ्रेडेड है?


25
ब्राउज़रों के संदर्भ में, शायद। लेकिन कुछ कार्यक्रम आपको जेएस को एक शीर्ष स्तर के लंगोट के रूप में मानते हैं और अन्य सी ++ कामों के लिए बाइंडिंग प्रदान करते हैं। उदाहरण के लिए, flusspferd (JS के लिए C ++ बाइंडिंग - AWESOME BTW) कुछ सामान मल्टीथ्रेडेड JS के साथ कर रहा था। यह संदर्भ तक है।
एन.जी.

11
यह अवश्य पढ़ें: developer.mozilla.org/en/docs/Web/JavaScript/EventLoop
Ricky

जवाबों:


583

यह एक अच्छा सवाल है। मुझे "हाँ" कहना अच्छा लगेगा। मैं नहीं कर सकता।

जावास्क्रिप्ट को आमतौर पर स्क्रिप्ट (*) के लिए दिखाई देने वाले निष्पादन का एक ही धागा माना जाता है, ताकि जब आपकी इनलाइन स्क्रिप्ट, ईवेंट श्रोता या टाइमआउट दर्ज किया जाए, तब तक आप पूरी तरह से नियंत्रण में रहें जब तक कि आप अपने ब्लॉक या फ़ंक्शन के अंत से वापस नहीं आते।

(*: इस सवाल को अनदेखा करते हुए कि क्या ब्राउज़र वास्तव में एक ओएस-थ्रेड का उपयोग करके अपने जेएस इंजनों को लागू करते हैं, या क्या अन्य सीमित थ्रेड-ऑफ-एक्जीक्यूशन वेबवर्कर्स द्वारा पेश किए जाते हैं।)

हालांकि, वास्तव में यह काफी डरपोक तरीके से सच नहीं है।

सबसे आम मामला तत्काल घटनाओं का है। जब आपका कोड उन्हें पैदा करने के लिए कुछ करता है, तो ब्राउज़र उन्हें तुरंत आग देगा:

var l= document.getElementById('log');
var i= document.getElementById('inp');
i.onblur= function() {
    l.value+= 'blur\n';
};
setTimeout(function() {
    l.value+= 'log in\n';
    l.focus();
    l.value+= 'log out\n';
}, 100);
i.focus();
<textarea id="log" rows="20" cols="40"></textarea>
<input id="inp">

log in, blur, log outआईई को छोड़कर सभी में परिणाम । ये घटनाएँ सिर्फ इसलिए नहीं बुझतीं क्योंकि आपने focus()सीधे फोन किया, वे हो सकता है क्योंकि आपने फोन किया alert(), या एक पॉप-अप विंडो खोली, या कुछ और जो फोकस को स्थानांतरित करता है।

यह अन्य घटनाओं में भी परिणाम कर सकता है। उदाहरण के लिए, एक i.onchangeश्रोता को जोड़ें और focus()कॉल को अनफोकस करने से पहले इनपुट में कुछ लिखें , और लॉग ऑर्डर log in, change, blur, log outऑपरा को छोड़कर, जहां यह log in, blur, log out, changeऔर IE है, जहां यह (यहां तक ​​कि अपेक्षाकृत कम) log in, change, log out, blur

इसी तरह click()एक तत्व पर कॉल करना जो इसे प्रदान करता है onclickतुरंत सभी ब्राउज़रों में हैंडलर को बुलाता है (कम से कम यह सुसंगत है!)।

(मैं on...यहां प्रत्यक्ष ईवेंट हैंडलर गुणों का उपयोग कर रहा हूं , लेकिन ऐसा ही होता है addEventListenerऔर attachEvent)

ऐसी परिस्थितियों का भी एक समूह है, जिसमें आपके कोड को थ्रेडेड करने के दौरान ईवेंट्स में आग लग सकती है, इसके बावजूद कि आप इसे भड़काने के लिए कुछ नहीं कर रहे हैं। एक उदाहरण:

var l= document.getElementById('log');
document.getElementById('act').onclick= function() {
    l.value+= 'alert in\n';
    alert('alert!');
    l.value+= 'alert out\n';
};
window.onresize= function() {
    l.value+= 'resize\n';
};
<textarea id="log" rows="20" cols="40"></textarea>
<button id="act">alert</button>

मारो alertऔर आपको एक मोडल डायलॉग बॉक्स मिलेगा। जब तक आप उस संवाद को खारिज नहीं करते, तब तक कोई और स्क्रिप्ट निष्पादित नहीं होती है? नहीं। मुख्य विंडो का आकार बदलें और आपको alert in, resize, alert outटेक्स्टारिया में मिलेगा ।

आपको लगता है कि एक मोडल डायलॉग बॉक्स के ऊपर एक विंडो का आकार बदलना असंभव है, लेकिन ऐसा नहीं है: लिनक्स में, आप विंडो को जितना चाहें उतना आकार बदल सकते हैं; विंडोज पर यह इतना आसान नहीं है, लेकिन आप स्क्रीन रिज़ॉल्यूशन को एक बड़े से छोटे में बदल सकते हैं, जहां खिड़की फिट नहीं होती है, जिससे इसे आकार दिया जा सकता है।

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

वे जगहें जहाँ आप उत्पन्न होने का कारण बन सकते हैं, स्क्रिप्ट को थ्रेडेड करते हुए उठाया जा सकता है:

  • जब मोडल पॉपअप ( alert, confirm, prompt), खुले सभी ब्राउज़रों लेकिन ओपेरा में हैं,

  • showModalDialogब्राउज़रों के दौरान जो इसका समर्थन करते हैं;

  • "इस पृष्ठ पर एक स्क्रिप्ट व्यस्त हो सकती है ..." संवाद बॉक्स, भले ही आप स्क्रिप्ट को चलाना जारी रखने का विकल्प चुनते हैं, आकार बदलने और धुंधला होने जैसी घटनाओं की अनुमति देता है और स्क्रिप्ट के बीच में होने तक भी नियंत्रित किया जा सकता है। ओपेरा में छोड़कर, व्यस्त-पाश।

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

  • शायद अधिक। जब से मैंने इसका परीक्षण किया है, तब से कुछ समय हो गया है और ब्राउज़र ने जटिलता प्राप्त कर ली है।

सारांश में, जावास्क्रिप्ट ज्यादातर उपयोगकर्ताओं को दिखाई देता है, ज्यादातर समय, एक सख्त घटना-चालित निष्पादन का एक धागा होता है। वास्तव में, यह कोई ऐसी बात नहीं है। यह स्पष्ट नहीं है कि यह केवल एक बग और कितना जानबूझकर डिजाइन है, लेकिन यदि आप जटिल एप्लिकेशन, विशेष रूप से क्रॉस-विंडो / फ़्रेम-स्क्रिप्टिंग लिख रहे हैं, तो हर मौका है कि यह आपको काट सकता है - और रुक-रुक कर, कठिन-से-डिबग तरीके।

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


14
@ जेपी: व्यक्तिगत रूप से मैं सीधे नहीं जानना चाहता क्योंकि इसका मतलब है कि मुझे सावधान रहना होगा कि मेरा कोड फिर से प्रवेश कर रहा है, मेरे ब्लर कोड को कॉल करने से यह प्रभावित नहीं होगा कि कुछ बाहरी कोड पर निर्भर है। ऐसे बहुत से मामले हैं जहां धुंधला होना एक अप्रत्याशित दुष्प्रभाव है, जो हर एक को पकड़ना जरूरी है। और दुर्भाग्य से अगर आप यह चाहते हैं, तो भी यह विश्वसनीय नहीं है! IE के blur बाद आपका कोड ब्राउजर पर नियंत्रण लौटाता है।
बोबिन्स

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

34
लेकिन, याद रखें कि सहकारी थ्रेडिंग अभी भी सिंगल थ्रेडेड है। दो चीजें एक साथ नहीं हो सकती हैं जो बहु-सूत्रण की अनुमति देता है और गैर-नियतात्मकता को इंजेक्ट करता है। जो कुछ वर्णित किया गया था वह निर्धारक है, और यह इन प्रकार के मुद्दों के बारे में एक अच्छा अनुस्मारक है। विश्लेषण पर अच्छा काम @bobince
chubbsondubs

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

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

115

मैं हां कहूंगा - क्योंकि वस्तुतः सभी मौजूदा (कम से कम सभी गैर-तुच्छ) जावास्क्रिप्ट कोड टूट जाएगा यदि ब्राउज़र का जावास्क्रिप्ट इंजन इसे अतुल्यकालिक रूप से चलाने के लिए था।

इस तथ्य को जोड़ें कि एचटीएमएल 5 पहले से ही वेब वर्कर्स को निर्दिष्ट करता है (मल्टी-थ्रेडिंग जावास्क्रिप्ट कोड के लिए एक स्पष्ट, मानकीकृत एपीआई) जो मूल जावास्क्रिप्ट में मल्टी-थ्रेडिंग को पेश करता है, वह ज्यादातर व्यर्थ होगा।

( अन्य टिप्पणीकारों पर ध्यान दें: भले ही setTimeout/setInterval, HTTP-request onload इवेंट्स (XHR), और UI इवेंट्स (क्लिक, फ़ोकस आदि) मल्टी-थ्रेडेडनेस की एक क्रूड छाप प्रदान करते हैं - वे अभी भी सभी को एक ही टाइमलाइन के साथ निष्पादित करते हैं - एक पर एक समय - इसलिए भले ही हम उनके निष्पादन आदेश को पहले से न जानते हों, किसी ईवेंट हैंडलर, समयबद्ध फ़ंक्शन या XHR कॉलबैक के निष्पादन के दौरान बाहरी परिस्थितियों को बदलने के बारे में चिंता करने की कोई आवश्यकता नहीं है।)


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

1
ध्यान दें कि एक ही है। मुख्य JS थ्रेड, लेकिन कुछ चीजें ब्राउज़र में समानांतर में चलाई जाती हैं। यह सिर्फ बहु-सूत्र की छाप नहीं है। अनुरोध वास्तव में समानांतर में चलाए जाते हैं। जेएस में आपके द्वारा परिभाषित श्रोताओं को एक-एक करके चलाया जाता है, लेकिन अनुरोध वास्तव में समानांतर हैं।
Nux

16

हां, हालांकि आप किसी भी अतुल्यकालिक APIs जैसे setInterval और xmlhttp कॉलबैक का उपयोग करते समय समवर्ती प्रोग्रामिंग (मुख्य रूप से दौड़ की स्थिति) के कुछ मुद्दों को पीड़ित कर सकते हैं।


10

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


8

मैं कहूंगा कि विनिर्देश किसी को एक इंजन बनाने से नहीं रोकता है जो कई थ्रेड्स पर जावास्क्रिप्ट चलाता है , जिससे कोड को साझा ऑब्जेक्ट स्थिति तक पहुंचने के लिए सिंक्रनाइज़ेशन करने की आवश्यकता होती है।

मुझे लगता है कि एकल-थ्रेडेड नॉन-ब्लॉकिंग प्रतिमान उन ब्राउज़रों में जावास्क्रिप्ट चलाने की आवश्यकता से बाहर आया जहां यूआई कभी भी ब्लॉक नहीं कर सकता।

Nodejs ने ब्राउज़रों के दृष्टिकोण का अनुसरण किया है ।

राइनो इंजन हालांकि, विभिन्न थ्रेड्स में रनिंग जेएस कोड का समर्थन करता है । निष्पादन संदर्भ साझा नहीं कर सकते, लेकिन वे गुंजाइश साझा कर सकते हैं। इस विशिष्ट मामले के लिए दस्तावेज में कहा गया है:

... "राइनो गारंटी देता है कि जावास्क्रिप्ट ऑब्जेक्ट्स के गुणों तक पहुंच धागे के पार परमाणु है, लेकिन एक ही समय में एक ही दायरे में निष्पादित स्क्रिप्ट के लिए कोई और गारंटी नहीं देता है। यदि दो स्क्रिप्ट एक ही स्कोप का एक साथ उपयोग करते हैं, तो स्क्रिप्ट हैं साझा चर के लिए किसी भी पहुँच के समन्वय के लिए जिम्मेदार है । "

राइनो प्रलेखन को पढ़ने से मैं यह निष्कर्ष निकालता हूं कि किसी के लिए एक जावास्क्रिप्ट एपीआई लिखना संभव हो सकता है जो नए जावास्क्रिप्ट थ्रेड्स भी पैदा करता है, लेकिन एपीआई राइनो-विशिष्ट होगा (उदाहरण के लिए नोड केवल एक नई प्रक्रिया को स्पॉन कर सकता है)।

मैं कल्पना करता हूं कि एक ऐसे इंजन के लिए भी जो जावास्क्रिप्ट में कई थ्रेड्स का समर्थन करता है, ऐसे स्क्रिप्ट के साथ संगतता होनी चाहिए जो मल्टी-थ्रेडिंग या ब्लॉकिंग पर विचार नहीं करते हैं।

Concearning ब्राउज़रों और NodeJS तरह से मैं यह है देखें:

    1. क्या सभी js कोड को एक ही थ्रेड में निष्पादित किया जाता है ? : हाँ।
    1. क्या js कोड अन्य थ्रेड को चलाने का कारण बन सकता है ? : हाँ।
    1. क्या ये थ्रेड्स म्यूट जेएस निष्पादन संदर्भ ?: नहीं, लेकिन वे (प्रत्यक्ष / अप्रत्यक्ष रूप से?)) उस घटना कतार में जोड़ सकते हैं जहां से श्रोता निष्पादन संदर्भ को म्यूट कर सकते हैं । लेकिन मूर्ख मत बनो, श्रोता फिर से मुख्य धागे पर परमाणु चलाते हैं ।

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


वेब-कर्मचारियों के बारे में अपडेट:

वेब-वर्करों की मौजूदगी इस बात को और सही ठहराती है कि जावास्क्रिप्ट को बहु-सूत्रित किया जा सकता है, इस अर्थ में कि कोई जावास्क्रिप्ट में कोड बना सकता है जो एक अलग थ्रेड पर चलेगा।

हालाँकि: वेब-वर्कर पारंपरिक थ्रेड्स की समस्याओं पर अंकुश नहीं लगाते हैं जो निष्पादन के संदर्भ को साझा कर सकते हैं। उपरोक्त नियम 2 और 3 अभी भी लागू होते हैं , लेकिन इस बार जावास्क्रिप्ट में उपयोगकर्ता (js कोड लेखक) द्वारा थ्रेडेड कोड बनाया गया है।

विचार करने के लिए केवल एक चीज की संख्या है, जो दक्षता से (और संगामिति नहीं ) दृष्टिकोण से, थ्रेडेड थ्रेड्स की संख्या है । निचे देखो:

धागा सुरक्षा के बारे में :

वर्कर इंटरफ़ेस वास्तविक OS-लेवल थ्रेड्स को जन्म देता है, और माइंडफुल प्रोग्रामर चिंतित हो सकते हैं कि यदि आप सावधान नहीं हैं तो कंसीडर आपके कोड में "दिलचस्प" प्रभाव पैदा कर सकता है।

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


पुनश्च

सिद्धांत के अलावा, स्वीकार किए गए उत्तर पर वर्णित संभावित कोने के मामलों और बगों के बारे में हमेशा तैयार रहें


7

JavaScript / ECMAScript होस्ट वातावरण के भीतर रहने के लिए डिज़ाइन की गई है। यह है कि, जावास्क्रिप्ट वास्तव में नहीं है कुछ भी कर जब तक मेजबान वातावरण पार्स और किसी दिए गए स्क्रिप्ट को निष्पादित, और पर्यावरण वस्तुओं है कि जाने जावास्क्रिप्ट वास्तव में उपयोगी हो (जैसे ब्राउज़रों में डोम के रूप में) प्रदान करने के लिए फैसला किया।

मुझे लगता है कि एक दिया गया फंक्शन या स्क्रिप्ट ब्लॉक लाइन-बाय-लाइन निष्पादित करेगा और यह जावास्क्रिप्ट के लिए गारंटी है। हालाँकि, शायद एक मेजबान वातावरण एक ही समय में कई स्क्रिप्ट निष्पादित कर सकता है। या, एक मेजबान वातावरण हमेशा एक वस्तु प्रदान कर सकता है जो मल्टी-थ्रेडिंग प्रदान करता है। setTimeoutऔर setIntervalउदाहरण के लिए, या कम से कम छद्म उदाहरण हैं, एक मेजबान वातावरण के लिए कुछ संगति करने का एक तरीका प्रदान करता है (भले ही यह बिल्कुल संगामिति न हो)।


7

दरअसल, एक पेरेंट विंडो बच्चे या भाई-बहनों के साथ संवाद कर सकती है।


6

@ गोबिसन वास्तव में अपारदर्शी उत्तर प्रदान कर रहा है।

Mrr'srlygsson के जवाब से पीछे हटते हुए, जावास्क्रिप्ट को हमेशा इस साधारण तथ्य के कारण एकल-पिरोया जाता है: जावास्क्रिप्ट में सब कुछ एक ही समय के साथ निष्पादित होता है।

यह एकल-थ्रेडेड प्रोग्रामिंग भाषा की सख्त परिभाषा है।


4

नहीं।

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

मान लीजिए कि आपके पास निम्नलिखित कोड हैं ...

var list = [];
for (var i = 0; i < 10000; i++) {
  list[i] = i * i;
}

यह इस उम्मीद के साथ लिखा गया है कि लूप के अंत तक, लिस्ट में 10000 प्रविष्टियाँ होनी चाहिए जो कि इंडेक्स स्क्वॉयर हैं, लेकिन VM यह नोटिस कर सकता है कि लूप का प्रत्येक पुनरावृत्ति दूसरे को प्रभावित नहीं करता है, और दो थ्रेड्स का उपयोग करके पुन: व्याख्या करता है।

पहला सूत्र

for (var i = 0; i < 5000; i++) {
  list[i] = i * i;
}

दूसरा धागा

for (var i = 5000; i < 10000; i++) {
  list[i] = i * i;
}

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

जबकि मैं किसी भी वीएम को इस तरह से समानांतर कोड का पता लगाने के बारे में नहीं जानता, यह संभावना है कि यह भविष्य में जेआईटी वीएम के लिए अस्तित्व में आ सकता है, क्योंकि यह कुछ स्थितियों में अधिक गति प्रदान कर सकता है।

इस अवधारणा को आगे बढ़ाते हुए, यह संभव है कि वीएम को बहु-थ्रेडेड कोड में परिवर्तित करने के लिए कोड को एनोटेट किया जा सकता है।

// like "use strict" this enables certain features on compatible VMs.
"use parallel";

var list = [];

// This string, which has no effect on incompatible VMs, enables threading on
// this loop.
"parallel for";
for (var i = 0; i < 10000; i++) {
  list[i] = i * i;
}

चूंकि वेब कार्यकर्ता जावास्क्रिप्ट में आ रहे हैं, इसलिए यह संभावना नहीं है कि यह ... बदसूरत प्रणाली कभी अस्तित्व में आएगी, लेकिन मुझे लगता है कि यह कहना सुरक्षित है कि जावास्क्रिप्ट परंपरा से थ्रेडेड है।


2
अधिकांश भाषा परिभाषाओं को प्रभावी ढंग से एकल-सूत्रित किया गया है, और कहा गया है कि जब तक प्रभाव समान है तब तक मल्टीथ्रेडिंग की अनुमति है। (उदा। यूएमएल)
जेवॉन

1
मुझे केवल इस जवाब से सहमत होना होगा क्योंकि वर्तमान ECMAScript कोई प्रावधान नहीं करता है (हालांकि यकीनन मुझे लगता है कि समवर्ती ECMAScript निष्पादन संदर्भों के लिए इसे C के लिए कहा जा सकता है) । फिर, इस उत्तर की तरह, मैं तर्क देता हूं कि किसी भी कार्यान्वयन में समवर्ती धागे एक साझा स्थिति को संशोधित करने में सक्षम होते हैं, एक ECMAScript एक्सटेंशन है
यूजर 2864740

3

खैर, क्रोम मल्टीप्रोसेस है, और मुझे लगता है कि हर प्रक्रिया अपने स्वयं के जावास्क्रिप्ट कोड के साथ काम करती है, लेकिन जहां तक ​​कोड जानता है, यह "सिंगल-थ्रेडेड" है।

मल्टी-थ्रेडिंग के लिए जावास्क्रिप्ट में कोई भी समर्थन नहीं है, कम से कम स्पष्ट रूप से नहीं, इसलिए इससे कोई फर्क नहीं पड़ता।


2

मैंने थोड़े संशोधनों के साथ @ bobince का उदाहरण दिया है:

<html>
<head>
    <title>Test</title>
</head>
<body>
    <textarea id="log" rows="20" cols="40"></textarea>
    <br />
    <button id="act">Run</button>
    <script type="text/javascript">
        let l= document.getElementById('log');
        let b = document.getElementById('act');
        let s = 0;

        b.addEventListener('click', function() {
            l.value += 'click begin\n';

            s = 10;
            let s2 = s;

            alert('alert!');

            s = s + s2;

            l.value += 'click end\n';
            l.value += `result = ${s}, should be ${s2 + s2}\n`;
            l.value += '----------\n';
        });

        window.addEventListener('resize', function() {
            if (s === 10) {
                s = 5;
            }

            l.value+= 'resize\n';
        });
    </script>
</body>
</html>

इसलिए, जब आप रन दबाते हैं, तो अलर्ट पॉपअप करें और "सिंगल थ्रेड" करें, आपको कुछ इस तरह से देखना चाहिए:

click begin
click end
result = 20, should be 20

लेकिन अगर आप विंडोज पर ओपेरा या फ़ायरफ़ॉक्स में इसे चलाने की कोशिश करते हैं और स्क्रीन पर अलर्ट पॉपअप के साथ विंडो को अधिकतम / अधिकतम करते हैं, तो इसके लिए कुछ करना होगा:

click begin
resize
click end
result = 15, should be 20

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


-4

एक दूसरे के भीतर दो setTimeout फ़ंक्शन घोंसला करने की कोशिश करें और वे बहुपरत व्यवहार करेंगे (यानी, बाहरी टाइमर अपने फ़ंक्शन को निष्पादित करने से पहले आंतरिक एक के पूरा होने की प्रतीक्षा नहीं करेगा)।


5
क्रोम इसे सही तरीके से करता है, डननो जहां @ जम्स इसे मल्टीथ्रेडेड होते हुए देखता है ...: setTimeout(function(){setTimeout(function(){console.log('i herd you liek async')}, 0); alert('yo dawg!')}, 0)(रिकॉर्ड के लिए, यो डॉग को पहले आना चाहिए, फिर कंसोल लॉग आउटपुट)
टोर वालो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.