2009-02-28 21 views
26

अतुल्यकालिक कॉल हमेशा एक नया धागा बनाने करता है?क्या एक असीमित कॉल हमेशा एक नया धागा बना/कॉल करता है?

उदाहरण:

तो जावास्क्रिप्ट एकल लड़ी तो कैसे यह एक async पोस्टबैक कर सकते हैं? क्या यह वास्तव में अवरुद्ध हो रहा है जब तक कि यह कॉलबैक न हो जाए? यदि हां, तो क्या यह वास्तव में एक एसिंक कॉल है?

उत्तर

50

यह एक दिलचस्प सवाल है।

असिंक्रोनस प्रोग्रामिंग प्रोग्रामिंग का एक प्रतिमान है जो मुख्य रूप से सिंगल थ्रेडेड है, यानी "निरंतर निष्पादन के एक थ्रेड के बाद"।

आप जावास्क्रिप्ट का संदर्भ लें, इसलिए वेब ब्राउज़र के वातावरण में उस भाषा पर चर्चा करें। एक वेब ब्राउज़र प्रत्येक विंडो में जावास्क्रिप्ट निष्पादन के किसी एकल थ्रेड चलता है, यह और (जैसे XMLHttpRequest कॉल के रूप में) नेटवर्क कनेक्शन (जैसे onclick = "someFunction()" के रूप में) की घटनाओं को संभालती है।

<script> 
function performRequest() { 
    xmlhttp.open("GET", "someurl", true); 
    xmlhttp.onreadystatechange = function() { 
    if (xmlhttp.readyState == 4) { 
     alert(xmlhttp.responseText); 
    } 
    } 
    xmlhttp.send(sometext); 
} 
</script> 
<span onclick="performRequest()">perform request</span> 

(यह केवल अवधारणाओं के प्रदर्शन के लिए एक गैर-कामकाजी उदाहरण है)।

असीमित तरीके से सब कुछ करने के लिए, नियंत्रण धागे को 'मुख्य लूप' के रूप में जाना जाता है। एक मुख्य पाश इस तरह दिखता है:

while (true) { 
    event = nextEvent(all_event_sources); 
    handler = findEventHandler(event); 
    handler(event); 
} 

यह ध्यान रखना महत्वपूर्ण है कि यह 'व्यस्त लूप' नहीं है। यह एक नींद धागा की तरह है, गतिविधि होने की प्रतीक्षा कर रहा है। गतिविधि उपयोगकर्ता (माउस मूवमेंट, एक बटन क्लिक, टाइपिंग) से इनपुट हो सकती है, या यह नेटवर्क गतिविधि (सर्वर से प्रतिक्रिया) हो सकती है।

इसलिए उपरोक्त उदाहरण में

,

  1. जब अवधि पर उपयोगकर्ता क्लिक करता है, एक ButtonClicked घटना उत्पन्न होगा, findEventHandler() स्पैन टैग पर ऑनक्लिक ईवेंट मिलेगा, और फिर उस हैंडलर होगा घटना के साथ बुलाया।
  2. जब xmlhttp अनुरोध बनाई गई है, यह घटना सूत्रों के all_event_sources सूची में जोड़ा गया है।
  3. performRequest() फ़ंक्शन रिटर्न के बाद, mainloop nextEvent() कदम प्रतिक्रिया की प्रतीक्षा करने पर इंतज़ार कर रहा है। इस बिंदु पर संभालने से आगे की घटनाओं को 'अवरुद्ध' नहीं किया जा रहा है।
  4. डेटा रिमोट सर्वर से वापस आता है, nextEvent() नेटवर्क ईवेंट देता है, इवेंट हैंडलर ऑनरेस्टस्टेटchange() विधि, विधि को कहा जाता है, और एक चेतावनी() संवाद आग लगती है।

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

+0

उत्तर का संपादन "यह कोई मूल्य नहीं है" से अलग है "यह नोटिंग के लायक है" जो मुझे लगता है कि आपका इरादा है। बस पाठकों के लिए भ्रम से बचने के लिए – MadMurf

+0

@MadMurf: मैंने यह भी देखा .... और इसे ठीक किया। – mpen

+0

>> असिंक्रोनस प्रोग्रामिंग प्रोग्रामिंग का एक प्रतिमान है जो मुख्य रूप से सिंगल थ्रेडेड है << - यहां पैडेंटिक होने की कोशिश नहीं कर रहा है, लेकिन मुझे नहीं पता कि यह कथन सत्य कैसे है। क्या असीमित प्रोग्रामिंग थ्रेड के बारे में कुछ भी बताती है, अकेले एकल बनाम एकाधिक दें? – Lee

15

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

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

एक अतुल्यकालिक कॉलबैक के साथ, एक ही बात होता है! अंतर यह है कि subroutine प्रणाली द्वारा लागू किया जाता है, वर्तमान कोड द्वारा subroutine का आह्वान नहीं किया जाता है।

+1

>> एक असीमित कॉल एक नया धागा नहीं है << - मुझे लगता है कि यह एक भ्रामक बयान है। मुझे ऐसा कुछ भी पता नहीं है जो जेएस को नए धागे के साथ एक्सएचआर अनुरोध की सेवा करने से रोकता है। मुझे लगता है कि आपका मतलब है कि एक नया धागा विनिर्देशन द्वारा गारंटी या सुझाव नहीं दिया गया है, लेकिन निश्चित रूप से यह सिस्टम द्वारा लागू किया जा सकता है। – Lee

4

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

5

एक जोड़े नोट:

XMLHttpRequest रों डिफ़ॉल्ट रूप से गैर अवरुद्ध कर रहे हैं। send() अंतर्निहित नेटवर्क स्टैक पर अनुरोध को रिले करने के तुरंत बाद विधि वापस आती है। सर्वर से एक प्रतिक्रिया अन्य उत्कृष्ट उत्तरों द्वारा चर्चा के अनुसार इवेंट लूप पर आपके कॉलबैक का आविष्कार शेड्यूल करेगी।

यह एक नया धागा आवश्यकता नहीं है। अंतर्निहित सॉकेट एपीआई जावा में java.nio.channels के समान चयन योग्य है।

यह open() के लिए तीसरे पैरामीटर के रूप में false पास करके तुल्यकालिकXMLHttpRequest वस्तुओं के निर्माण के लिए संभव है। यह जब तक एक प्रतिक्रिया सर्वर से प्राप्त किया गया है, इस प्रकार नेटवर्क विलंबता की दया पर घटना पाश रखने और संभावित नेटवर्क का समय समाप्त होने तक ब्राउज़र फांसी send() विधि ब्लॉक करने के लिए कारण होगा। यह एक बुरी चीज ™ है।

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

+0

जब आपने कहा था कि 'सर्वर से एक प्रतिक्रिया इवेंट लूप पर आपके कॉलबैक का आविष्कार शेड्यूल करेगी, जो/कौन सा धागा कॉलबैक को कॉलबैक का कारण बनने के लिए इवेंट लूप पर एक ईवेंट डालता है? – Yiling

+1

@Yiling यह घटना ब्राउज़र में एक I/O थ्रेड आंतरिक द्वारा बनाई गई है, न कि जावास्क्रिप्ट को सक्रिय करने वाला धागा। – Matthew

2

नहीं, लेकिन एक से अधिक धागा शामिल किया जाएगा।

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

यदि आप इस संदर्भ में एक सिंक्रोनस कॉल करना चाहते हैं, तो आपको एक संदेश पोस्ट करने और सक्रिय रूप से कॉलबैक होने की प्रतीक्षा करनी होगी।

तो सारांश में: एक से अधिक धागे शामिल होंगे, लेकिन यह आवश्यक रूप से एक नया धागा नहीं बनायेगा।

2

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

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

संबंधित मुद्दे