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


269

क्या यह एक जानबूझकर किया गया निर्णय है या हमारे वर्तमान ब्राउज़रों के साथ एक समस्या है जिसे आने वाले संस्करणों में ठीक किया जाएगा?


3
वेब वर्कर / वर्कर थ्रेड्स के बारे में जानकारी के लिए जावास्क्रिप्ट और थ्रेड्स प्रश्न के उत्तर भी देखें ।
सैम हसलर

115
हैलो, साथी गोगलर। आप देख सकते हैं कि यहां सब कुछ काफी दिनांकित है (ध्यान दें कि यह प्रश्न 5 साल पहले पूछा गया था।) चूंकि यह पूछा गया था, वेब ब्राउज़रों ने कुछ क्षमताएं हासिल की हैं, जहां तक ​​मैं बता सकता हूं, कम या ज्यादा मल्टीथ्रेडिंग हैं। वेब वर्कर्स पर एक नज़र डालें: msdn.microsoft.com/en-us/hh549259.aspx
ArtOfWarfare

2
Multithread.js वेब वर्कर्स को लपेटता है और JS में आसान मल्टीथ्रेडिंग की अनुमति देता है। IOS सफारी सहित सभी नए ब्राउज़रों पर काम करता है। :)
किलोवाट

जवाबों:


194

जावास्क्रिप्ट मल्टी-थ्रेडिंग का समर्थन नहीं करता है क्योंकि ब्राउज़र में जावास्क्रिप्ट दुभाषिया एक एकल धागा (AFAIK) है। यहां तक ​​कि Google Chrome किसी भी वेब पेज के जावास्क्रिप्ट को समवर्ती रूप से चलने नहीं देगा क्योंकि इससे मौजूदा वेब पेजों में बड़े पैमाने पर समसामयिक मुद्दे हो जाएंगे। सभी क्रोम अलग-अलग प्रक्रियाओं में कई घटकों (अलग-अलग टैब, प्लग-इन, वगैरह) को अलग करते हैं, लेकिन मैं एक पृष्ठ की एक से अधिक जावास्क्रिप्ट थ्रेड होने की कल्पना नहीं कर सकता।

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

हम जावास्क्रिप्ट में एक अमूर्त पुस्तकालय का उपयोग करते हैं जो हमें प्रक्रियाओं और धागे बनाने की अनुमति देता है जो सभी एक ही जावास्क्रिप्ट दुभाषिया द्वारा प्रबंधित होते हैं। यह हमें निम्नलिखित तरीके से कार्य चलाने की अनुमति देता है:

  • प्रक्रिया ए, धागा १
  • प्रक्रिया ए, थ्रेड 2
  • प्रक्रिया बी, धागा 1
  • प्रक्रिया ए, थ्रेड 3
  • प्रक्रिया ए, थ्रेड 4
  • प्रक्रिया बी, धागा 2
  • प्रक्रिया को रोकें
  • प्रक्रिया बी, धागा 3
  • प्रक्रिया बी, धागा 4
  • प्रक्रिया बी, धागा 5
  • प्रक्रिया A प्रारंभ करें
  • प्रक्रिया ए, थ्रेड 5

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

जावास्क्रिप्ट के भविष्य के लिए, इसे देखें : https://developer.mozilla.org/pretations/xtech2006/javascript.in


73
मुझे लगता है कि कभी लागू नहीं किया गया एक दृष्टि बहुत संकीर्ण है। मैं गारंटी देता हूं कि वेब ऐप्स अंततः बहु-प्रत्यक्ष रूप से सक्षम होंगे (यह केवल तार्किक है, क्योंकि वेब ऐप अधिक प्रभावी हो जाते हैं, और हार्डवेयर अधिक समानांतर हो जाता है), और जैसा कि मैं इसे देखता हूं, क्योंकि जावास्क्रिप्ट वेब विकास की वास्तविक भाषा है, यह अंततः मल्टीथ्रेडिंग का समर्थन करना होगा या ऐसा कुछ करने से प्रतिस्थापित किया जाएगा।
devios1

6
कभी-कभी शायद बहुत अधिक बोल्ड स्टेटमेंट नहीं होता है :) लेकिन मुझे अभी भी लगता है कि सच्चे मल्टीथ्रेडेड जावास्क्रिप्ट के फायदे भविष्य के भविष्य में संभव नहीं हैं;)
कामिल वानरोइज

5
हालाँकि मैं तर्क दूंगा कि वेब वर्कर्स एक थ्रेड-मॉडल की तुलना में प्रक्रिया-मॉडल के माध्यम से अधिक समवर्ती हैं। वेब कार्यकर्ता संदेश पासिंग को संचार के साधन के रूप में उपयोग करते हैं, जो कि बहु-विषयक अनुप्रयोगों में 'सामान्य' समसामयिक मुद्दों का एक सुरुचिपूर्ण समाधान है। मुझे यकीन नहीं है कि वे वास्तव में मुख्य पृष्ठ के समान वस्तुओं पर काम कर सकते हैं। जहाँ तक मुझे पता है वे DOM तक नहीं पहुँच सकते। हालांकि, अधिकांश यह शब्दार्थ है, वेब कार्यकर्ता सभी उद्देश्यों और उद्देश्यों के लिए आशाजनक दिखते हैं।
कामिल वानरोइज

कठिनाइयाँ अतिरिक्त संभावनाओं से बड़ी होती हैं, यदि आप सभी अतिरिक्त संभावनाओं के बारे में सोचते हैं तो मुझे यकीन नहीं है। मैं विशेष रूप से उन मामलों के बारे में सोच रहा हूं जहां वेबलॉग का उपयोग गेम या ग्राफिकल विज़ुअलाइज़ेशन की तरह होता है। उदाहरण के लिए Google मैप्स के नए 3D संस्करण पर विचार करें। कई 3 डी मॉडल वाले शहरों में मेरे पीसी को सब कुछ लोड करने के लिए ~ 2 मिनट की आवश्यकता होती है जब कई घरों को प्रस्तुत करना पड़ता है। कुछ निश्चित कोणों पर न तो मेरे ग्राफिक्स कार्ड और न ही मेरे नेटवर्क की क्षमता काम कर रही है। लेकिन 8 में से 1 प्रोसेसर 100% पर है। एफपीएस के संदर्भ में मल्टीथ्रेडिंग भी एक बड़ी चिंता है क्योंकि इस उदाहरण से पता चलता है: youtube.com/watch?v=sJ2p982cZFc
सिंधिक्स

25

जावास्क्रिप्ट मल्टी-थ्रेडिंग (कुछ सीमाओं के साथ) यहाँ है। Google ने गियर्स के लिए श्रमिकों को लागू किया, और श्रमिकों को HTML5 के साथ शामिल किया जा रहा है। अधिकांश ब्राउज़र इस सुविधा के लिए पहले ही समर्थन जोड़ चुके हैं।

डेटा की थ्रेड-सुरक्षा की गारंटी है क्योंकि कार्यकर्ता से / के लिए संचारित सभी डेटा क्रमबद्ध / कॉपी किए गए हैं।

अधिक जानकारी के लिए, पढ़ें:

http://www.whatwg.org/specs/web-workers/current-work/

http://ejohn.org/blog/web-workers/


8
लेकिन क्या यह बहु-थ्रेडेड के बजाय बहु-प्रक्रिया दृष्टिकोण के अधिक नहीं है? थ्रेड्स को एक ही ढेर के भीतर काम करने के लिए जाना जाता है।
गोमांस पंख

1
@ बेइफ्थर, यह सच है। यह एक प्रक्रिया दृष्टिकोण के अधिक है।
नील

23

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

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

@marcio :

क्यों जावास्क्रिप्ट में मल्टी-थ्रेडिंग को लागू नहीं करने का एक कारण है? प्रोग्रामर अपने पास मौजूद उपकरणों के साथ जो चाहें कर सकते हैं।

तो, आइए, उन्हें ऐसे उपकरण न दें जो दुरुपयोग करना इतना आसान है कि मेरे द्वारा खोली गई हर दूसरी वेबसाइट मेरे ब्राउज़र को क्रैश कर दे। इसका एक निष्किय कार्यान्वयन आपको सीधे उस क्षेत्र में लाएगा, जिसने IE7 विकास के दौरान एमएस को बहुत सारे सिरदर्द का कारण बनाया: ऐड-ऑन लेखकों ने थ्रेडिंग मॉडल के साथ तेज और ढीला खेला, जिसके परिणामस्वरूप छिपे हुए कीड़े दिखाई दिए जो प्राथमिक थ्रेड पर ऑब्जेक्ट जीवनचक्र बदल जाने पर स्पष्ट हो गए। । खराब। यदि आप IE के लिए बहु-थ्रेडेड ActiveX ऐड-ऑन लिख रहे हैं, तो मुझे लगता है कि यह क्षेत्र के साथ आता है; इसका मतलब यह नहीं है कि इससे आगे जाने की जरूरत है।


6
"यह जोखिम को कम करता है> अनुभवहीन जेएस कोडर्स> थ्रेड्स के साथ गड़बड़ करने की अनुमति देने में" क्यों यह जावास्क्रिप्ट में मल्टी-थ्रेडिंग को लागू नहीं करने का एक कारण है? प्रोग्रामर अपने पास मौजूद उपकरणों के साथ जो चाहें कर सकते हैं। अगर यह अच्छा है या बुरा, यह उनकी समस्या है। Google Chrome प्रक्रिया मॉडल के साथ यह अन्य अनुप्रयोगों को भी प्रभावित नहीं कर सकता है। :)
मार्सिओ अगुयार

3
@ शोग 9 - "चलो [प्रोग्रामर] टूल्स न दें जो कि दुरुपयोग करने में बहुत आसान हैं कि मैं जो दूसरी वेबसाइट खोलता हूं वह मेरे ब्राउज़र को क्रैश कर दे।" - क्या? उसी तर्क से, किसी भी भाषा को मल्टीथ्रेडिंग नहीं करना चाहिए, क्योंकि यदि उन्होंने प्रस्ताव दिया कि आपके द्वारा खोला गया हर दूसरा प्रोग्राम क्रैश हो जाएगा। सिवाय इसके कि इस तरह से काम नहीं करता है। थ्रेडिंग अधिकांश भाषाओं में मौजूद है और अधिकांश नौसिखिए प्रोग्रामर इसे नहीं छूते हैं, और उनमें से अधिकांश जो इसे उत्पादन में नहीं डालते हैं, और वे ऐप जो कभी लोकप्रिय या व्यापक रूप से उपयोग नहीं किए जाते हैं।
आर्टऑफवर्फ

11

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

बस आपका काम थोड़ा सा काम करता है, और फिर कुछ इस तरह कॉल करें:

setTimeout(function () {
    ... do the rest of the work...
}, 0);

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


अधिकांश मामलों में मैं loopअंदर का उपयोग करना चाहूंगा , setTimeoutलेकिन जाहिर है कि यह काम नहीं करता है। क्या आपने ऐसा कुछ किया है या आपके पास हैक है? एक उदाहरण 1000 तत्व की सरणी के लिए होगा, मैं दो setTimeoutकॉल के अंदर दो छोरों के लिए उपयोग करने की उम्मीद करता हूं, जैसे कि पहले छोरों के माध्यम से और प्रिंट तत्व 0..499, दूसरा छोरों के माध्यम से और प्रिंट तत्व 500..999
बेंजामिन

आमतौर पर तकनीक राज्य को बचाने और जारी रखने के लिए होती है। उदाहरण के लिए, मान लें कि आप 0 से 1000 तक प्रिंट करना चाहते हैं, आप 0 से 499 प्रिंट कर सकते हैं और फिर सेटटाइमआउट ट्रिक को 500 तर्क के साथ कर सकते हैं। कोड के अंदर तर्क (500) लेना और वहां से लूप शुरू करना जानते हैं।
ईयाल

8

क्या आपका मतलब है कि भाषा मल्टीथ्रेडिंग का समर्थन क्यों नहीं करती है या ब्राउज़र में जावास्क्रिप्ट इंजन मल्टीथ्रेडिंग का समर्थन क्यों नहीं करते हैं?

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


6

Node.js 10.5+ वर्कर थ्रेड्स को प्रायोगिक सुविधा के रूप में समर्थन करता है (आप इसका उपयोग कर सकते हैं - -परिमेंटल-वर्कर फ़्लैग सक्षम के साथ): https://nodejs.org/api/worker_threads.html

तो, नियम है:

  • यदि आपको I / O बाध्य ऑप्स करने की आवश्यकता है , तो आंतरिक तंत्र का उपयोग करें (उर्फ कॉलबैक / वादा / async-इंतजार)
  • यदि आपको सीपीयू बाउंड ऑप्स करने की आवश्यकता है , तो कार्यकर्ता थ्रेड्स का उपयोग करें।

वर्कर थ्रेड्स का उद्देश्य लंबे समय तक जीवित रहने वाले धागे हैं, जिसका अर्थ है कि आप एक बैकग्राउंड थ्रेड स्पॉन करते हैं और फिर आप मैसेज पासिंग के माध्यम से इसके साथ संवाद करते हैं।

अन्यथा, यदि आपको एक अनाम फ़ंक्शन के साथ एक भारी सीपीयू लोड को निष्पादित करने की आवश्यकता है, तो आप https://github.com/wilk/microjob के साथ जा सकते हैं , एक छोटा पुस्तकालय जो श्रमिक थ्रेड्स के आसपास बनाया गया है।


4

जैसा कि मैट बी ने कहा, सवाल बहुत स्पष्ट नहीं है। यह मानते हुए कि आप भाषा में मल्टीथ्रेडिंग समर्थन के बारे में पूछ रहे हैं: क्योंकि वर्तमान में ब्राउज़र में चल रहे अनुप्रयोगों के 99.999% के लिए इसकी आवश्यकता नहीं है। यदि आपको वास्तव में इसकी आवश्यकता है, तो वर्कअराउंड हैं (जैसे कि window.setTimeout का उपयोग करना)।

सामान्य रूप से मल्टीथ्रेडिंग बहुत, बहुत, बहुत, बहुत, बहुत कठिन है (क्या मैंने कहा है कि यह कठिन है?) सही पाने के लिए, जब तक आप अतिरिक्त प्रतिबंधों में नहीं डालते हैं (जैसे कि केवल अपरिवर्तनीय डेटा का उपयोग करना)।


3

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

कुछ और उपयोगी लिंक:

वेब अनुप्रयोगों के लिए एक कम्प्यूटिंग राजमार्ग का निर्माण


2

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


1

यह कार्यान्वयन है जो मल्टी-थ्रेडिंग का समर्थन नहीं करता है। वर्तमान में Google गियर्स बाहरी प्रक्रियाओं को निष्पादित करके संक्षिप्त रूप में कुछ का उपयोग करने का एक तरीका प्रदान कर रहा है, लेकिन यह इसके बारे में है।

नया ब्राउज़र Google आज जारी करने वाला है (Google Chrome) कुछ कोड को समानांतर में प्रक्रिया में अलग करके निष्पादित करता है।

मूल भाषा, निश्चित रूप से जावा का कहना है, के रूप में एक ही समर्थन हो सकता है, लेकिन Erlang की संगति की तरह कुछ का समर्थन क्षितिज के पास कहीं नहीं है।


1

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


0

जहाँ तक मैंने सुना है Google क्रोम में मल्टीथ्रेडेड जावास्क्रिप्ट होगा, तो यह "वर्तमान कार्यान्वयन" समस्या है।


0

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


-1

हालाँकि आप कंसेंट टू सेंपल को लाने के लिए eval फंक्शन का उपयोग कर सकते हैं

/* content of the threads to be run */
var threads = [
        [
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');"
        ],
        [
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');"
        ]
    ];

window.onload = function() {
    var lines = 0, quantum = 3, max = 0;

    /* get the longer thread length */
    for(var i=0; i<threads.length; i++) {
        if(max < threads[i].length) {
            max = threads[i].length;
        }
    }

    /* execute them */
    while(lines < max) {
        for(var i=0; i<threads.length; i++) {
            for(var j = lines; j < threads[i].length && j < (lines + quantum); j++) {
                eval(threads[i][j]);
            }
        }
        lines += quantum;
    }
}

-2

HTML5 द्वारा लाए गए वेबवर्क का उपयोग करके जावास्क्रिप्ट के साथ मल्टी-थ्रेडिंग स्पष्ट रूप से संभव है।

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

कई रूपरेखाएं थ्रेड्स के बीच प्रोग्राम संरचना की अनुमति देने के लिए मौजूद हैं, उनमें से OODK-JS, समवर्ती प्रोग्रामिंग का समर्थन करने वाला एक OOP js फ्रेमवर्क https://github.com/GOMServices/oodk-js-oop-for-js


5
साझाकरण मेमोरी एक अलग प्रक्रिया (जैसे कांटा () बनाम निष्पादन) () के विपरीत थ्रेड की सटीक परिभाषा है। थ्रेड्स ऑब्जेक्ट साझा कर सकते हैं, प्रक्रियाओं को आईपीसी का उपयोग करना चाहिए। वेब वर्कर्स मल्टीथ्रेडिंग नहीं हैं।
felixfbecker
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.