Thursday 15 March 2018

Waitforexit - रुक जाता है


इसकी पिछली बार जब मैंने ब्लॉग किया था, तब से एक वर्ष से अधिक रहा I इसके लिए क्षमा करें, लेकिन यह एक व्यस्त वर्ष रहा है। Ive फिर से लेने का फैसला किया है और एक समय में कुछ तकनीकी संबंधित यादृच्छिक विचार पोस्ट करने की कोशिश। आज मैं सिर्फ एक बग साझा करना चाहता था जो मैंने पाया था कि आप में से कुछ के लिए दिलचस्प हो सकते हैं। मेरे पास एक छोटा सा समारोह था जो एक प्रक्रिया शुरू कर चुका था और इसके काम को पूरा करने के लिए इंतजार किया था। कोड इस तरह से कुछ देखा गया: प्रक्रिया पी नई प्रक्रिया () पी। स्टार्टइनफ़ो। यूसे शेल। झूठी पी। स्टार्टइनफ़ोइट। रीडायरेक्टस्टाडोडाओटपुट सच पी। स्टार्टइनफ़ो। रीडायरेक्टस्टार्डअरेक्ट सच P. StartInfo. FileName पथटोप्रोग्राम पी। स्टार्ट इन्फॉ.अर्गग्राम प्रोग्रामअर्जेंट्स पी। स्टार्ट () पी। WaitForExit () P. Close () प्रक्रिया को कुछ समय के लिए खत्म करने के लिए कुछ समय लगता है, इसलिए मैं देखना चाहता था कि क्या हो रहा था, इसलिए मैंने stderrstdinput से पढ़ने का फैसला किया कि क्या कुछ गलत हो गया है। ऐसा करने के लिए, मुझे यकीन है कि प्रक्रिया के पुनर्निर्देशन मानक एंटर गुणों को सही (ऊपर कोड देखें) पर सेट किया गया था, और यह जांचने के लिए कि क्या एप्लिकेशन में कोई त्रुटि आई है, तो निम्न पंक्ति डाली गई है: P. WaitForExit () स्ट्रिंग त्रुटि P. StandardError। ReadToEnd () पी। क्लोज () कुछ समय के लिए इस कोड का इस्तेमाल किया गया था, मैंने देखा कि उपरोक्त प्रक्रिया करते समय एक बार आवेदन लंबित था। समस्या केवल तब हुई जब बहुत सारे डेटा मानकरेर को लिखे गए थे। मैंने इस समस्या को डीबग किया, और पाया कि मानक ईर्रॉ से पढ़ना छोड़ने से समस्या को हटा दिया गया मैंने सोचा कि यह एक अजीब समस्या की तरह लग रहा था, और एक समाधान के लिए खोज जारी रखा दस्तावेज़ीकरण को पढ़ने के बाद, अंत में मैं उस सूचना के साथ आया जो समस्या का पता चला। RedirectStandardError संपत्ति के लिए एमएसडीएन लाइब्रेरी में निम्नलिखित टिप्पणी है: प्रक्रिया घटक एक पाइप के उपयोग से बाल प्रक्रिया के साथ संचार करता है। यदि कोई बच्ची प्रक्रिया बफ़र को भरने के लिए पर्याप्त डेटा पाइप में लिखती है, तो बच्चे को तब तक अवरुद्ध कर दिया जाएगा जब तक कि माता-पिता पाइप से डेटा नहीं पढ़ते। यह डेडलॉक का कारण हो सकता है यदि आपका एप्लिकेशन मानक त्रुटि और मानक आउटपुट में सभी आउटपुट पढ़ रहा है, उदाहरण के लिए, निम्न C कोड का उपयोग कर। इसलिए बफर भरने के लिए प्रक्रिया को पूछने के बजाय और इसे खाली करने के लिए प्रतीक्षा करें ताकि WaitForExit () को कॉल करने से पहले WaitForExit () को कॉल करने से पहले बफर (P. StandardError. ReadToEnd ()) की सामग्री को पढ़ने के लिए अवरुद्ध किया जाएगा। समस्या और समाधान एक सफलता बना दिया निष्कर्ष: दस्तावेज़ पढ़ें। और यह सुनिश्चित कर लें कि आपने ये टिप्पणियां पढ़ ली हैं। कोड लगभग सभी की तरह दिखता है: जैसा कि आप देख सकते हैं, कोड एक सीएमडी। एक्ससी प्रक्रिया शुरू करता है और उस आदेश को पूरा करता है जिसे मैं निष्पादित करना चाहता हूं। मैं कोड से पढ़ने के लिए मानक ईर्रर और स्टैंडऑन आउटपुट को रीडायरेक्ट करता हूं। कोड प्रक्रिया से पहले उन्हें पढ़ता है WaitForExit (टाइमआउट) कॉल के रूप में Microsoft द्वारा अनुशंसित (और बाद में इस पर) समस्या तब उठती है जब मैं cmd. exe को भेजता हूं, कभी भी समाप्त नहीं होता है या अनिश्चित काल तक लटका रहता है। कोड में मैंने कमांड पिंग - t 8.8.8.8 का उपयोग किया था, जो - t ऑप्शन के कारण, बिना रोक के होस्ट को पिंग करता है। क्या होता है cmd. exe प्रक्रिया को ping - t कमांड के साथ कभी नहीं निकलता है और कभी भी stdout स्ट्रीम को बंद नहीं करता है और इसलिए हमारा कोड आउटपुट प्रक्रिया पर लटका हुआ है। StandardOutput. ReadToEnd () लाइन क्योंकि यह सभी स्ट्रीम को पढ़ने में सफल नहीं हो सकता। ऐसा भी होता है कि बैच फ़ाइल में किसी भी आदेश को किसी भी कारण से लटका दिया जाता है और इसलिए उपरोक्त कोड कई सालों तक लगातार काम कर सकता है और फिर बिना किसी स्पष्ट कारण के बिना अचानक लटका सकता है। इससे पहले कि मैंने लिखा था कि इसकी प्रक्रिया से पहले पुनः निर्देशित धाराओं को पढ़ने की सिफारिश की गई है। WaitForExit (टाइमआउट) कॉल, अच्छी तरह से यह विशेष रूप से सही है यदि आप टाइमआउट के बिना WaitForExit हस्ताक्षर का उपयोग करते हैं। यदि आप प्रक्रिया कॉल करते हैं रीडायरेक्ट स्ट्रीम पढ़ने से पहले WaitForExit (): कोड 2: यदि आप cmd. exe से जुड़ते हैं या आप जिस कॉल को कॉल करते हैं, तो मानक आउटपुट या मानक त्रुटि भरने पर आपको डेडलॉक का अनुभव हो सकता है यह इसलिए है क्योंकि हमारे कोड लाइनों तक पहुंच नहीं सकते हैं आउटपुट प्रक्रिया। मानक आउटपुट ReadToEnd () तथ्य की बात के रूप में बाल प्रक्रिया (पिंग कमांड या बैच फाइल या जो भी प्रक्रिया आप निष्पादित कर रहे हैं) खिचड़ी भाषा पर चलती है अगर हमारे प्रोग्राम में धाराओं के भरे बफ़र्स नहीं पढ़ा जाता है और ऐसा नहीं हो सकता क्योंकि कोड पर लटका हुआ है प्रक्रिया के साथ लाइन WaitForExit () जो बच्चे की परियोजना से बाहर निकलने के लिए हमेशा प्रतीक्षा करेंगे। दोनों धाराओं का डिफ़ॉल्ट आकार 4096 बाइट्स है। आप इन दो आकारों की इन बैच फ़ाइलों के साथ परीक्षण कर सकते हैं: पहला स्क्रिप्ट मानक आउटपुट के लिए 4096 बाइट्स लिखता है और मानक त्रुटि के लिए दूसरा है। इनमें से किसी एक को सी में सहेजें: testbuffsize. bat और हमारे प्रोग्राम कॉलिंग प्रक्रिया को चलाने के लिए। आउटपुट प्रक्रिया से पहले waitForExit () मानक आउटपुट कोड 2 में रीडटेन्ड () के रूप में आप इसे कमांड रिंगल्ट परिणाम ExecuteShellCommandSync (c: testbuffsize. bat, 1000) लिखकर कोड 13 की रेखा 13 पर लिख सकते हैं। कोड लटका नहीं है, लेकिन यदि आप दो धाराओं में से किसी एक में एक और बाइट लिखते हैं तो यह बफ़र आकार प्रोग्राम को बनाने से अधिक हो जाएगा लटका। यदि आपको मानक आउटपुट या स्टैंडर त्रुटि को रीडायरेक्ट करने और पढ़ने की आवश्यकता है तो सबसे अच्छा समाधान उन्हें एसिंक्रोनस तरीके से पढ़ना है। ऐसा करने का एक शानदार तरीका मार्क बॉयर्स द्वारा इस स्टैक ओवरफ्लो थैरे में प्रस्तावित किया गया है पिछले बात के अनुसार कृपया ध्यान दें कि अगर बच्चा प्रक्रिया केवल इसलिए निकलती है क्योंकि आप इस प्रक्रिया का उपयोग करते हैं। WaitForExit (टाइमआउट) हस्ताक्षर और यह वास्तव में टाइमआउट में चला जाता है, आपको सीएमडी.एक्सए प्रक्रिया और उसके संभावित बच्चों को मारना चाहिए।

No comments:

Post a Comment