2010-04-19 16 views
9

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

मान लीजिए कि मेरे पास उपभोक्ता/निर्माता पैटर्न है। अगर मैं उपभोक्ता या निर्माता को थ्रॉटल करना चाहता हूं, जो उपयोग करना बेहतर है, सो या उपज? मैं ज्यादातर फ़ंक्शन का उपयोग करने की दक्षता में रूचि रखता हूं।

+1

न तो, आप इसे अवरुद्ध करना चाहते हैं। Google "बाध्य बफर"। –

उत्तर

9

निर्माता/उपभोक्ता को कोड करने का "सही" तरीका उपभोक्ता के डेटा के लिए उपभोक्ता का इंतजार करना है। आप एक म्यूटेक्स जैसे सिंक्रनाइज़ेशन ऑब्जेक्ट का उपयोग कर इसे प्राप्त कर सकते हैं। उपभोक्ता Wait म्यूटेक्स पर होगा, जो डेटा उपलब्ध होने तक इसे निष्पादित करने से रोकता है। बदले में, उत्पादक उपलब्ध होने पर निर्माता म्यूटेक्स को संकेत देगा, जो उपभोक्ता धागे को जगाएगा ताकि यह प्रसंस्करण शुरू हो सके। यह दोनों के संदर्भ में sleep तुलना में अधिक कुशल है:

  • CPU उपयोग (कोई चक्र बर्बाद हो जाते हैं), और
  • भागो समय (निष्पादन डेटा प्राप्त होते ही उपलब्ध है, जब नहीं एक धागा जगाने के लिए निर्धारित है शुरू होता है तक)।

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

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

आप शायद थोड़े समय के लिए सो सकते हैं (शायद usleep का उपयोग करके, एक सेकंड से भी कम समय के लिए) या सिंक्रनाइज़ेशन ऑब्जेक्ट का उपयोग करने के लिए बेहतर है जैसे कि म्यूटेक्स को संकेत मिलता है कि डेटा उपलब्ध है।

+0

नींद केवल सेकंड में निष्पादन को निलंबित कर सकती है, नैनोस्ली एक सेकंड के अंशों में निष्पादन को निलंबित कर सकती है। – Ernelli

+0

@ कर्नेल जो कार्यान्वयन विवरण है। – Anycorn

+0

मैं जस्टिन की सिफारिश का जिक्र कर रहा था कि नींद का उपयोग एक सेकंड से कम समय के लिए करें। लेकिन सिंक्रनाइज़ेशन का उपयोग करने के लिए सही तरीका निश्चित रूप से है। – Ernelli

1

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

इस स्थिति में पैदा होने से वास्तव में बहुत मदद नहीं होती है क्योंकि यादृच्छिक बैकऑफ की संभावना बढ़ सकती है कि थ्रेड भुखमरी नहीं होती है।

संपादित करें: हालांकि मुझे पता है कि यह जरूरी नहीं है कि यह जावा विशिष्ट है। Thread.sleep(0) का जावा कार्यान्वयन Thread.yield() का समान प्रभाव है उस बिंदु पर शैली के मामले में इसकी अधिकता है।

10

नींद और उपज समान नहीं है। नींद बुलाते समय प्रक्रिया/थ्रेड दिए गए समय के लिए सीपीयू को दूसरी प्रक्रिया/थ्रेड देता है।

उपज सीपीयू को दूसरे थ्रेड पर छोड़ देता है, लेकिन यदि सीपीयू के लिए इंतजार करने वाले कोई अन्य धागे नहीं हैं तो तत्काल वापस आ सकते हैं।

तो यदि आप थ्रॉटल करना चाहते हैं, उदाहरण के लिए नियमित अंतराल पर डेटा स्ट्रीम करते समय, नींद या नैनोस्ली उपयोग करने के लिए कार्य है।

यदि निर्माता/उपभोक्ता के बीच सिंक्रनाइज़ेशन की आवश्यकता है, तो आपको एक म्यूटेक्स/सशर्त प्रतीक्षा का उपयोग करना चाहिए।

0

जावा में, कुछ जेवीएम कार्यान्वयन थ्रेड का इलाज करते हैं।उपज() को नो-ऑप के रूप में, जिसका अर्थ है कि इसका कोई प्रभाव नहीं पड़ सकता है। कॉलिंग Thread.sleep() का मतलब यह नहीं है कि शेड्यूलर को सीपीयू को किसी अन्य धागे में लाया जाना चाहिए; यह कार्यान्वयन भी निर्भर है। यह संदर्भ-स्विच के साथ जुड़े लागत को कम करने के लिए संदर्भित हो सकता है या यह किसी अन्य थ्रेड पर स्विच कर सकता है।

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