2013-06-07 8 views
9

मुझे पता है कि यदि आप बाह्य प्रक्रिया शुरू करने के लिए का उपयोग करते हैं तो को अपने stdout/stderr का उपभोग करें (उदा। here देखें)। अन्यथा बाहरी प्रक्रिया शुरू होने पर लटकती है।यदि माता-पिता जावा में stdout/stderr का उपभोग नहीं करते हैं तो प्रक्रिया क्यों लटकाती है?

मेरा प्रश्न क्यों यह इस तरह से काम करता है। मेरा अनुमान है कि JVM निष्पादित प्रक्रिया के stdout/stderr को पाइप पर रीडायरेक्ट करता है और यदि पाइपों में पाइप ब्लॉक पर कोई कमरा नहीं है। क्या इस का कोई मतलब निकलता है?

अब मुझे आश्चर्य है कि क्यों जावा ऐसा करता है। इस डिजाइन के पीछे तर्क क्या है?

+3

और क्या किया जाना चाहिए? क्या धाराओं को आसानी से अनदेखा किया जाना चाहिए? इस तरह कॉलर को धाराओं को पढ़ने के लिए मजबूर किया जाता है। –

+0

@UwePlonus की तरह कहा; यदि आप वास्तव में उन सभी को अनदेखा करना चाहते हैं, तो बस किसी प्रकार का 'देवनुल {इनपुट, आउटपुट} स्ट्रीम' या कुछ बनाएं (JVM भी पहले से ही हो सकता है, मुझे नहीं पता) – fge

+1

बीटीडब्लू, ठीक वही बात होगी यूनिक्स कमांड लाइन यदि आप std {out, err} को किसी नामित पाइप पर रीडायरेक्ट करते हैं और इससे नहीं पढ़ते हैं। – fge

उत्तर

10

जावा इस क्षेत्र में कुछ भी नहीं करता है। यह पाइप बनाने के लिए ओएस सेवाओं का उपयोग करता है।

ओएस और विंडोज जैसे सभी यूनिक्स इस संबंध में समान व्यवहार करते हैं: 4K के साथ एक पाइप माता-पिता और बच्चे के बीच बनाई जाती है। जब वह पाइप भर जाती है (क्योंकि एक तरफ पढ़ नहीं रहा है), लेखन प्रक्रिया ब्लॉक।

यह पाइप की शुरुआत के बाद से मानक है। ज्यादा जावा नहीं कर सकता है।

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

मुझे लगता है कि वर्तमान API के दो कारण हैं। सबसे पहले, जावा डेवलपर्स (यानी सूर्य/ओरेकल के लोग) जानते हैं कि प्रक्रिया एपीआई कैसे काम करती है और आपको क्या करना है। वे इतना जानते हैं कि ऐसा नहीं हुआ कि एपीआई भ्रमित हो सकता है।

दूसरा कारण यह है कि बहुमत के लिए काम करने वाला कोई अच्छा डिफ़ॉल्ट नहीं है। आप वास्तव में माता-पिता और बच्चे के stdin कनेक्ट नहीं कर सकते हैं; यदि आप कंसोल पर कुछ टाइप करते हैं, तो इनपुट को किस प्रक्रिया में जाना चाहिए?

इसी प्रकार, यदि आप स्टडआउट कनेक्ट करते हैं, तो आउटपुट कहीं भी जाएगा। यदि आपके पास कोई वेब ऐप है, तो कोई कंसोल नहीं हो सकता है या आउटपुट कहीं कहीं जा सकता है जहां कोई भी इसकी अपेक्षा नहीं करेगा।

पाइप भरने पर आप अपवाद भी नहीं फेंक सकते हैं क्योंकि सामान्य ऑपरेशन के दौरान भी हो सकता है।

+1

महोदय, क्या हमें प्रोसेसबिल्डर के इनपुटस्ट्रीम और त्रुटि स्ट्रीम दोनों को पढ़ने के लिए दो बाहरी धागे की आवश्यकता है और waitFor() को कॉल करने से पहले इसे निष्पादित करें? – saurabheights

6

यह javadoc of Process में समझाया गया है:

डिफ़ॉल्ट रूप से, बनाया उपप्रक्रिया अपने स्वयं के टर्मिनल या सांत्वना नहीं है। इसके सभी मानक I/O (यानी stdin, stdout, stderr) संचालन को मूल प्रक्रिया में रीडायरेक्ट किया जाएगा, जहां उन्हें आउटपुट आउटपुटस्ट्रीम(), getInputStream(), getErrorStream(), और getErrorStream() प्राप्त करने वाली विधियों का उपयोग करके प्राप्त किया जा सकता है। अभिभावक प्रक्रिया इनपुट को फ़ीड करने और उपप्रोसेसर से आउटपुट प्राप्त करने के लिए इन धाराओं का उपयोग करती है। क्योंकि कुछ देशी प्लेटफ़ॉर्म केवल मानक इनपुट और आउटपुट स्ट्रीम के लिए सीमित बफर आकार प्रदान करते हैं, इनपुट स्ट्रीम को तत्काल लिखने में विफलता या उपप्रोसेस की आउटपुट स्ट्रीम को पढ़ने में उपप्रोसेसर को अवरुद्ध करना पड़ सकता है, या यहां तक ​​कि डेडलॉक भी हो सकता है।

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

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