2013-05-19 17 views
5

धारावाहिक संचार के लिए उपयोग किए जाने वाले बहु-थ्रेडेड लिनक्स प्रोग्राम में, क्या यह संभव है (और सबसे अच्छा तरीका क्या होगा) किसी अन्य थ्रेड से अवरुद्ध पढ़ने() कॉल को समाप्त करने के लिए?लिनक्स, ब्लॉकिंग को रद्द करना रद्द करें()

मैं सब कुछ यथासंभव प्रतिक्रियाशील रखना चाहता हूं और बार-बार मतदान के साथ टाइमआउट के किसी भी उपयोग से बचना चाहता हूं।

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

+0

संबंधित: https://stackoverflow.com/questions/384391/how-to-signal-select-to-return-immediately –

उत्तर

7

एक काफी लोकप्रिय चाल: पढ़ने() में अवरुद्ध करने के बजाय, अपने सीरियल-सॉकेट और पाइप दोनों पर चयन() में ब्लॉक करें। फिर जब कोई और धागा आपके धागे को जगा लेना चाहता है, तो वह उस पाइप के दूसरे छोर पर एक बाइट लिखकर ऐसा कर सकता है। उस बाइट का चयन करने के लिए चयन() का कारण बन जाएगा और आपका धागा अब सफाई और बाहर निकल सकता है या जो कुछ भी करने की ज़रूरत है। (ध्यान दें कि यह काम 100% विश्वसनीय रूप से करने के लिए आप शायद अपने सीरियल-सॉकेट को गैर-अवरुद्ध करने के लिए सेट करना चाहते हैं, यह सुनिश्चित करने के लिए कि आपका थ्रेड केवल चुनिंदा() में ब्लॉक करता है और कभी भी पढ़ा नहीं जाता है())

+1

सेकेंड किया गया। मैं इस तरह से लगभग सभी मेरे multithreaded प्रोग्रामिंग करते हैं। यह संचार अनुक्रमिक प्रक्रियाओं (सीएसपी) से बाहर एक पैटर्न है। यह देखते हुए कि स्कैला स्कैला ऑब्जेक्ट्स (सीएसपी का व्यावहारिक कार्यान्वयन) का संचार करता है, मुझे लगता है कि आपको सुझाव बहुत उपयुक्त है। बीटीडब्लू विंडोज़ Win32 या .NET के लिए प्रोग्रामिंग की सबसे बड़ी कमी यह है कि आप पाइप पर() एक बड़े पैमाने पर चूक का चयन नहीं कर सकते हैं। एमएस आपको विश्वास करेगा कि एसिंक आईओ बेहतर है, लेकिन यह वास्तव में गन्दा कोड की ओर जाता है। सिग्विन परियोजना में चुनने में समस्याएं थीं()। उनके समाधान में बहुत सारे धागे और मतदान शामिल हैं। – bazza

+0

FWIW आप एक ही चाल (केवल 10 बार प्रयास के साथ;) के तहत कर सकते हैं) विंडोज के तहत दो टीसीपी सॉकेट और कनेक्टिंग() को उनमें से एक को दिखाकर, जैसा कि यहां दिखाया गया है: http://code.google.com /p/imagesoft/source/browse/trunk/rpcrt4/socketpair.c?r=5 –

+1

उत्तर के लिए धन्यवाद! चयन मेरे लिए काम नहीं किया (शायद मैंने कुछ गलत किया), हालांकि चयन() मैन पेज पढ़ने के दौरान मैंने मतदान() पर ठोकर खाई। यह पूरी तरह से काम किया :) –

4

AFAIK संकेत ब्लॉकिंग सिस्टम कॉल से किसी भी थ्रेड को तोड़ने का एकमात्र तरीका है।

यूएसआर 1 सिग्नल के साथ धागे के उद्देश्य से pthread_kill() का उपयोग करें।

+0

उत्तर के लिए धन्यवाद, लेकिन मेरे उपयोग-मामले में एक pthread_kill संभव नहीं होगा (क्योंकि फ़ंक्शंस से कॉल किया जाता है एक जेवीएम के विभिन्न धागे)। क्या कोई कामकाज मैं उपयोग कर सकता हूं? मैंने एपोल के बारे में कुछ सामान सुना लेकिन मेरे परीक्षण भी काम नहीं कर पाए। –

+0

मुझे सिफारिश करने के लिए जेएनआई के बारे में पर्याप्त जानकारी नहीं है। आप एक थ्रेड से 'एपोल' और दूसरे से 'क्लोज़()' का उपयोग कर सकते हैं, लेकिन मेरा मानना ​​है कि यह अनिर्धारित व्यवहार है। – kja

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