2017-12-10 162 views
6

मैं आई/ओ समापन बंदरगाहों समझने की कोशिश कर रहा हूँ और विशेष रूप से कैसे वे async का उपयोग कर से संबंधित हैं - await आई/ओ के लिए। IOCPs के बारे मेंक्या आईओसीपी एक धागा है जो आई/ओ हो रहा है या उसके बाद हो रहा है?

कुख्यात लेख There is No Thread वार्ता संक्षिप्त उधार दिए जाने के बाद आई/ओ पूरा हो गया है। चूंकि आलेख का पूरा बिंदु यह दिखाने के लिए है कि जब फैंसी हार्डवेयर-स्तर I/O सामान उड़ान में है, तो

क्या कोई थ्रेड नहीं है, अभी तक I/O किया गया है ? नहीं। क्या I/O अभी तक किया गया है? नहीं। क्या I/O अभी तक किया गया है? सं ...

लेकिन तब मैं this article पर देख रहा हूँ जो कहता है कि एक

"घटक पंक्तिबद्ध तत्वों के लिए पूरा होने के बंदरगाह की जाँच के प्रभारी है"

और

public class IOCompletionWorker 
{ 
    public unsafe void Start(IntPtr completionPort) 
    { 
     while (true) 
     { 
      uint bytesRead; 
      uint completionKey; 
      NativeOverlapped* nativeOverlapped; 

      var result = Interop.GetQueuedCompletionStatus(
       completionPort, 
       out bytesRead, 
       out completionKey, 
       &nativeOverlapped, 
       uint.MaxValue); 

      var overlapped = Overlapped.Unpack(nativeOverlapped); 

      if (result) 
      { 
       var asyncResult = ((FileReadAsyncResult)overlapped.AsyncResult); 
       asyncResult.ReadCallback(bytesRead, asyncResult.Buffer); 
      } 
      else 
      { 
       ThreadLogger.Log(Interop.GetLastError().ToString()); 
      } 

      Overlapped.Free(nativeOverlapped); 
     } 
    } 
} 

जैसे उदाहरण देता है 0
var completionPortThread = new Thread(() => new IOCompletionWorker().Start(completionPortHandle)) 
{ 
    IsBackground = true 
}; 
completionPortThread.Start(); 

जो मेरे लिए कुछ मतदान चल रहा है की तरह लग रहा है।

मुझे लगता है कि मेरे सवालों

  • करने के लिए नीचे उबाल यह है कि एक .NET अनुप्रयोग धागा पूल के 2 प्रकार है कहने के लिए सच है - (2) "मैं/हे (1)" कार्यकर्ता धागे 'और धागे '?
  • यदि यह सच है, वहाँ एक निश्चित संख्या, एक विन्यास में निर्दिष्ट, एम कार्यकर्ता धागे और एन आई/ओ धागे की तरह है? और आम तौर पर एम से एन का अनुपात क्या होता है?
  • जब I/O धागे ठीक से उपयोग किए जाते हैं?
+0

क्या आपके प्रश्न का उत्तर दिया गया है? :) – fbrosseau

उत्तर

5

दोनों लेख अपने तरीके से सही हैं।

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

एक उदाहरण के रूप में नेटवर्क सॉकेट लेते हैं, लेकिन इस अतुल्यकालिक काम के किसी भी प्रकार के लिए सही हो जाएगा:

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

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

आईओसीपी का मुद्दा यह है कि आप हजारों आईओ हैंडल (सॉकेट, फाइल, ...) को एक एकल आईओसीपी से बांध सकते हैं। फिर आप समानांतर में उन हजारों एसिंक्रोनस प्रक्रियाओं को चलाने के लिए एक थ्रेड का उपयोग कर सकते हैं।

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

आईओसीपी का मुख्य बिंदु विंडोज के तहत एसिंक्रोनस ऑपरेशंस के प्रभावशाली समांतरता को प्राप्त करना है।

मुझे उम्मीद है कि यह भ्रम को स्पष्ट करता है।

विशिष्ट प्रश्न

  1. हाँ के लिए के रूप में, नेट ढांचा दो पूल हैं। एक उपयोगकर्ता-मोड सामान्य उद्देश्य के काम, "वर्कर" थ्रेडपूल के लिए पूरी तरह से है। दूसरा "आईओ" थ्रेडपूल है। यह दूसरा ऐसा है कि उच्च स्तर के सी # कोड लिखते समय सभी आईओसीपी प्रबंधन आपके से छिपाए जा सकते हैं और ताकि आपकी असीमित सॉकेट सिर्फ जादू की तरह काम करे।
  2. यह सभी कार्यान्वयन विवरण है जो किसी भी समय बदल सकता है, लेकिन जवाब यह है कि दोनों पूल स्वतंत्र हैं। यदि आपके पास कार्यकर्ता थ्रेडपूल पर भारी कार्य बैंडविड्थ हो रहा है और ढांचे का निर्णय है कि आपका थ्रूपुट नए थ्रेड जोड़कर बढ़ेगा, तो यह अकेले वर्कर पूल में धागे जोड़ देगा, और आईओ पूल को छूएगा। आईओ पूल के लिए भी यही है, अगर आपके पास कोड का गलत व्यवहार है जो आईओ थ्रेड्स को उनके कॉलबैक में अवरुद्ध करता है, तो यह नए आईओ पूल पैदा करेगा और कार्यकर्ता पूल को छूएगा। आप ThreadPool.SetMinThreads/SetMaxThreads का उपयोग करके संख्याओं को कस्टमाइज़ कर सकते हैं, लेकिन यह आमतौर पर एक संकेत है कि आपकी प्रक्रिया थ्रेडपूल का दुरुपयोग करती है।
  3. आईओ थ्रेड का उपयोग तब किया जाता है जब थ्रेडपूल के आंतरिक आईओसीपी से हटाए गए आइटम होते हैं। सामान्य कोड में, यह तब होगा जब कुछ आईओ हैंडल पर एक एसिंक्रोनस ऑपरेशन पूरा हो गया हो। आप UnsafeQueueNativeOverlapped के माध्यम से स्वयं आइटम कतार भी कर सकते हैं, लेकिन यह बहुत कम आम है।

शुद्ध कामयाब अतुल्यकालिक परिचालन (कर की तरह Task.Delay साथ async-का इंतजार है, उदाहरण के लिए) किसी भी IO संभाल शामिल नहीं है, और इसलिए वे न करना पड़े कुछ चालक द्वारा एक IOCP में पोस्ट किए जाने, और इसलिए वे "वर्कर" श्रेणी के अंतर्गत आते हैं।

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

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