2009-02-27 11 views
21

आसान बनाने के लिए, यह एक स्थिति है जहाँ एक NamedPipe सर्वर एक NamedPipe ग्राहकब्रेकिंग ReadFile() अवरुद्ध - नामांकित पाइप (विंडोज एपीआई)

Windows API (WriteFile() का प्रयोग करके) पाइप के लिए लिखने के लिए इंतज़ार कर रहा है है कि ब्लॉक कर रहा है ReadFile है()

सर्वर अवरुद्ध साथ तुल्यकालिक पाइप (कोई ओवरलैप आई/ओ) बनाया गया है

ग्राहक जुड़े है सक्षम है, और अब सर्वर कुछ डेटा के लिए इंतजार कर रहा है।

चीजों के सामान्य प्रवाह में, क्लाइंट कुछ डेटा भेजता है और सर्वर इसे संसाधित करता है और फिर डेटा के अगले हिस्से की प्रतीक्षा करने के लिए ReadFile() पर वापस आता है।

इस बीच एक घटना होती है (उदाहरण के लिए उपयोगकर्ता इनपुट) और नामांकित पाइप सर्वर को अब कुछ अन्य कोड निष्पादित करना होगा, जो रीडफाइल() अवरुद्ध होने पर ऐसा नहीं कर सकता है।

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

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

एक और धागा

DisconnectNamedPipe() 

और

CloseHandle() 

वे दोनों नहीं लौटेगा बुला मैं कोशिश की है से

(जब तक ग्राहक पाइप के लिए लिखता है।)

मैं कनेक्ट नहीं कर सकता एक ही पाइप और कुछ बाइट्स लिखें क्योंकि:

"नाम के सभी उदाहरण पाइप एक ही पाइप नाम साझा करते हैं, लेकिन प्रत्येक उदाहरण में अपने स्वयं के बफर और हैंडल हैं, और क्लाइंट/सर्वर संचार के लिए एक अलग कंडिट प्रदान करता है। "

http://msdn.microsoft.com/en-us/library/aa365590.aspx

मैं इसे नकली करने का उपाय की जरूरत है, तो $ 64k डॉलर सवाल है:

मैं कैसे ReadFile को अवरुद्ध तोड़ सकते हैं()?

उत्तर

1

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

मेरे करियर में कभी भी मुझे "अधिक धागे" == "कम स्केलेबल" नहीं मिला है। आपके पास इनमें से कितने "सर्वर" उदाहरण हैं?

आम तौर पर, अगर ऑपरेशन अवरुद्ध हो रहा है और ऑपरेशन अवरुद्ध होने पर सिस्टम को उत्तरदायी होने की आवश्यकता है तो एक ऑपरेशन को एक अलग थ्रेड में निष्पादित करने की आवश्यकता है।

+0

इनमें से कितने "सर्वर" उदाहरण करते हैं आपके पास? वे 10k तक के बारे में बात कर रहे हैं ... मुझे पता है कि ओवरहेड कम है, लेकिन विचार इसे कम करना है। मैं सिर्फ सवाल पूछ रहा हूं ... क्या यह संभव है? –

+0

मुझे नहीं लगता कि आपके पास 10k धागे हो सकते हैं :-) – alex2k8

+0

हां, जिसके लिए थ्रेड पूल की आवश्यकता होगी, लेकिन बिंदु यह है कि एक नया थ्रेड शुरू करने के साथ एक प्रदर्शन ओवरहेड है, और प्रत्येक थ्रेड को इसके ढेर के लिए कुछ स्मृति आवंटित की जाती है आदि यह जोड़ता है और अवांछनीय है। –

2

माइक,

आप सिंक्रोनस रीडफाइल को रद्द नहीं कर सकते हैं। लेकिन आप एसिंक्रोनस (ओवरलैप्ड) ऑपरेशंस पर स्विच कर सकते हैं। ऐसा करके, आप एक सुंदर स्केलेबल आर्किटेक्चर को कार्यान्वित कर सकते हैं।

संभव एल्गोरिथ्म (सिर्फ एक विचार):

  • प्रत्येक नए ग्राहक कॉल ReadFile
  • WaitForMultipleObjects जहां हैंडल overlapped.hEvent + अपने कस्टम घटनाओं
  • दोहराएं हैं पर घटनाओं का संकेत के लिए, और अनुसूची उन्हें धागे पूल से धागे द्वारा निष्पादन के लिए।

इस तरह आप कनेक्शन प्राप्त करने और डेटा पढ़ने के लिए केवल कुछ धागे प्राप्त कर सकते हैं, जबकि वास्तविक डेटा प्रोसेसिंग थ्रेड पूल द्वारा किया जा सकता है।

+0

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

5

लंबित तुल्यकालिक आई/ओ कार्य है कि निर्दिष्ट धागा द्वारा जारी किए जाते हैं के रूप में रद्द कर दिया CancelSynchronousIo

मार्क्स पर एक नजर डालें।

और CancelIo/CancelIoEx:

सभी लंबित अतुल्यकालिक मैं/हे कार्यवाही रद्द करने के लिए, का उपयोग करें या तो:

CancelIo - इस समारोह के लिए ही बुला धागा द्वारा जारी किए गए संचालन रद्द निर्दिष्ट फ़ाइल हैंडल।

CancelIoEx - यह फ़ंक्शन निर्दिष्ट फ़ाइल हैंडल के लिए थ्रेड द्वारा जारी किए गए संचालन को रद्द करता है।

+0

ओह। मैं याद किया कि ... न्यूनतम समर्थित ग्राहक \t Windows Vista न्यूनतम समर्थित सर्वर \t विंडोज सर्वर 2008 दुर्भाग्य से यह विंडोज सर्वर 2003 अरे –

+1

'MSDN सिंक्रोनस और एसिंक्रोनस आई/ओ' लेख के लिए गूगल है। लगता है कि छोड़ा गया एकमात्र विकल्प टर्मिनेट थ्रेड है, लेकिन यह एक बुरा विचार होगा ('msdn TerminateThread के लिए Google निम्नलिखित समस्याओं का परिणाम हो सकता है') – alex2k8

+0

अधिक जानकारी यहां: http://msdn.microsoft.com/en-us/library/ aa480216.aspx ("विंडोज Vista में Win32 I/O रद्दीकरण समर्थन")। –

0

अतुल्यकालिक मैं/हे संचालन किसी भी धागा ब्लॉक करने के लिए यदि वे आई/ओ समापन बंदरगाहों का उपयोग नहीं है। देखें: http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx

11

ReadFile से पहले इस प्रयास करें:

BOOL WINAPI PeekNamedPipe(
    __in  HANDLE hNamedPipe, 
    __out_opt LPVOID lpBuffer, 
    __in  DWORD nBufferSize, 
    __out_opt LPDWORD lpBytesRead, 
    __out_opt LPDWORD lpTotalBytesAvail, 
    __out_opt LPDWORD lpBytesLeftThisMessage 
); 

if(TotalBytesAvail > 0) 
    ReadFile(....); 

-AV-

+0

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

+0

ग्रेट स्टफ, यह अज्ञात पाइप के लिए भी काम करता है –

0

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

+0

लोगों को इसका जवाब पता है 8 साल के साथी के लिए सवाल, अब जवाब क्यों? – Droopy

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