मैं सी/सी ++ में एक पॉज़िक्स संगत बहु थ्रेडेड सर्वर लिख रहा हूं जो बड़ी संख्या में स्वीकार करने, पढ़ने और लिखने में सक्षम होना चाहिए असीमित कनेक्शन। सर्वर में कई कार्यकर्ता धागे हैं जो कार्य करते हैं और कभी-कभी (और अप्रत्याशित रूप से) क्यू डेटा को सॉकेट में लिखा जाना है। डेटा कभी-कभी (और अप्रत्याशित रूप से) ग्राहकों द्वारा सॉकेट को लिखा जाता है, इसलिए सर्वर को अतुल्यकालिक रूप से भी पढ़ना चाहिए। ऐसा करने का एक स्पष्ट तरीका यह है कि प्रत्येक कनेक्शन को एक धागा दें जो उसकी सॉकेट से/पढ़ता है और लिखता है; यह बदसूरत है, हालांकि, प्रत्येक कनेक्शन लंबे समय तक जारी रह सकता है और सर्वर को कनेक्शन का ट्रैक रखने के लिए सौ या हजार धागे पकड़ना पड़ सकता है।एक शर्त (pthread_cond_wait) और एक सॉकेट परिवर्तन (चयन) पर एक साथ प्रतीक्षा कर रहे हैं
एक बेहतर दृष्टिकोण एक एकल धागा होना चाहिए जो चुनिंदा()/pselect() फ़ंक्शंस का उपयोग करके सभी संचारों को संभाला जाए। यानी, एक धागा किसी भी सॉकेट पर पठनीय होने की प्रतीक्षा करता है, फिर इनपुट को संसाधित करने के लिए एक नौकरी पैदा करता है जिसे इनपुट उपलब्ध होने पर अन्य धागे के पूल द्वारा संभाला जाएगा। जब भी अन्य कार्यकर्ता धागे कनेक्शन के लिए आउटपुट उत्पन्न करते हैं, तो यह कतारबद्ध हो जाता है, और संचार धागा उस सॉकेट को लिखने से पहले लिखने योग्य होने के लिए इंतजार कर रहा है।
समस्या यह है कि संचार थ्रेड सर्वर के कार्यकर्ता थ्रेड द्वारा कतारबद्ध होने पर चयन() या pselect() फ़ंक्शन में प्रतीक्षा कर रहा है। यह संभव है कि, यदि कोई इनपुट कई सेकंड या मिनट के लिए आता है, तो आउटपुट का एक कतारबद्ध हिस्सा संचार थ्रेड को चुनने के लिए इंतजार करेगा() आईएनजी। ऐसा नहीं होना चाहिए, हालांकि - डेटा जितनी जल्दी हो सके लिखा जाना चाहिए।
अभी मैं थ्रेड-सुरक्षित होने के लिए कुछ समाधान देखता हूं। एक संचार थ्रेड व्यस्त है-इनपुट पर प्रतीक्षा करें और सॉकेट की सूची अपडेट करें जो यह एक या दूसरे के दसवें लिखने के लिए इंतजार कर रहा है। यह इष्टतम नहीं है क्योंकि इसमें व्यस्त प्रतीक्षा शामिल है, लेकिन यह काम करेगा। एक और विकल्प pselect() का उपयोग करना है और जब भी नया आउटपुट कतारबद्ध किया जाता है, तो यूएसआर 1 सिग्नल (या कुछ समतुल्य) भेजना, जिससे संचार थ्रेड को सॉकेट की सूची अपडेट करने की इजाजत मिलती है, जो तुरंत लिखने योग्य स्थिति के लिए प्रतीक्षा कर रहा है। मैं बाद वाले को पसंद करता हूं, लेकिन फिर भी किसी शर्त के लिए सिग्नल का उपयोग करना नापसंद करता है (pthread_cond_t)। फिर भी एक और विकल्प फ़ाइल डिस्क्रिप्टरों की सूची में शामिल करना होगा, जिस पर चयन() इंतजार कर रहा है, एक डमी फ़ाइल जिसे हम एक बाइट लिखते हैं जब भी किसी सॉकेट को चुनने योग्य fd_set में चयन() के लिए जोड़ा जाना चाहिए; यह संचार सर्वर को जगाएगा क्योंकि उस विशेष डमी फ़ाइल को तब पठनीय किया जाएगा, इस प्रकार संचार थ्रेड को इसके लिखने योग्य fd_set को तुरंत अपडेट करने की अनुमति मिल जाएगी।
मुझे सहजता से लगता है कि दूसरा प्रोग्राम (सिग्नल के साथ) सर्वर प्रोग्राम करने का 'सबसे सही' तरीका है, लेकिन अगर कोई जानता है कि उपरोक्त में से कौन सा सबसे कुशल है, आम तौर पर बोल रहा है, चाहे उपर्युक्त में से कोई भी ऐसी दौड़ स्थितियों का कारण बनता है जिनके बारे में मुझे पता नहीं है, या यदि कोई इस समस्या के अधिक सामान्य समाधान के बारे में जानता है। जो मैं वास्तव में चाहता हूं वह एक pthread_cond_wait_and_select() फ़ंक्शन है जो कमेट थ्रेड को सॉकेट में बदलाव या किसी शर्त से सिग्नल पर इंतजार करने की अनुमति देता है।
अग्रिम धन्यवाद।