क्या समान सॉकेट पर भेजने / पुनः प्राप्त करने के लिए समानांतर कॉल मान्य हैं?


127
  1. क्या हम एक थ्रेड से कॉल भेज सकते हैं और एक ही सॉकेट पर दूसरे से रिकवर कर सकते हैं?
  2. क्या हम एक ही सॉकेट पर अलग-अलग थ्रेड्स से कई बार कॉल भेज सकते हैं?

मुझे पता है कि एक अच्छे डिज़ाइन को इससे बचना चाहिए, लेकिन मैं स्पष्ट नहीं हूं कि ये सिस्टम एपीआई कैसे व्यवहार करेंगे। मैं एक अच्छा प्रलेखन भी उसी के लिए नहीं पा रहा हूँ।

दिशा में कोई भी संकेत सहायक होगा।


3
आप दावा क्यों करते हैं कि ऐसा करना एक बुरा अभ्यास है? यह मेरे लिए ठीक है क्योंकि आप विभिन्न धागों में सुनते हैं और प्राप्त करते हैं।
TheMathNoob

जवाबों:


92

POSIX परमाणु कार्यों के रूप में भेजने / पुनरावृत्ति को परिभाषित करता है, इसलिए यह मानते हुए कि आप POSIX भेजने / पुनरावृत्ति के बारे में बात कर रहे हैं, हाँ, आप उन्हें एक साथ कई थ्रेड से कॉल कर सकते हैं और काम करेंगे।

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

यदि आप SOCK_STREAM सॉकेट्स का उपयोग कर रहे हैं, तो चीजों को समानांतर करने की कोशिश करना कम उपयोगी है क्योंकि सेंड / रिकव किसी संदेश का केवल एक भाग भेज या प्राप्त कर सकता है, जिसका अर्थ है कि चीजें विभाजित हो सकती हैं।

SOCK_STREAM सॉकेट्स पर सेंड / रिकव को तब तक ब्लॉक करें जब तक वे कम से कम 1 बाइट भेजते या फिर से ब्लॉक न कर दें, इसलिए ब्लॉकिंग और नॉन-ब्लॉकिंग के बीच का अंतर उपयोगी नहीं है।


1
@ जोआओ: SOCK_DGRAM सॉकेट को "संदेश सीमाओं को संरक्षित करने" के रूप में प्रलेखित किया जाता है, जो बहुत स्पष्ट नहीं है। लिनक्स कर्नेल स्रोतों को देखने से आप कम से कम यह देख सकते हैं कि प्रत्येक एक पैकेट को अनौपचारिक रूप से (कम से कम udp के लिए) भेजता है और पुन: पेश करता है।
क्रिस डोड

2
@ केदार: निश्चित नहीं कि आपका क्या मतलब है। एक sendही रिटर्न डेटा भेजने के बफर में रखा जाता है, और डेटा netowrk ढेर के माध्यम से और बाहर पर भेज दिया जाता है नेटवर्क पर एसिंक्रोनस रूप के रूप में। इसलिए यदि आपके पास एक थ्रेड भेजने और एक थ्रेड प्राप्त करने वाला है, तो थ्रेड भेजने के लिए इसकी पूरी तरह से संभव (यहां तक ​​कि संभावना) है कि पहले पैकेट प्राप्त करने से पहले कई पैकेट भेजे जाएं। इसकी पूरी तरह से अतुल्यकालिक और एक साथ नहीं।
क्रिस डोड

6
@ क्रिसडॉड, क्या आप "परमाणु संचालन के रूप में पोसिक्स डिफाइन सेंड / रिकव" के लिए एक लिंक दे सकते हैं?
सुआतेंशी

2
@suitianshi: POSIX 1003.1c मानक दस्तावेज़ 1003.1 में सभी कार्यों को सूचीबद्ध करता है जो कि रीएंन्टेंट (थ्रेड्स से कॉल करने के लिए सुरक्षित) हैं और जो नहीं हैं। मैं दुर्भाग्य से कहीं भी उपलब्ध एक मुफ्त ऑनलाइन कॉपी के बारे में नहीं जानता।
क्रिस डोड

2
मैं @ChrisDodd पर प्रतिलिपि पाया है unix-systems.org/version4 और मैं अध्याय 7.1 पर सिस्टम इंटरफ़ेस टेबल की सूची देख सकते हैं, लेकिन नहीं दिख रहा है जहां यह कार्यों की सूची परमाणु संचालन होने के रूप में। आपको संदेह नहीं है, लेकिन क्या आप दस्तावेज़ में अपनी बात को सही ठहराने के लिए अपना जवाब साझा / संपादित कर सकते हैं?
user153882

17

सॉकेट डिस्क्रिप्टर प्रक्रिया के अंतर्गत आता है, किसी विशेष धागे के लिए नहीं। इसलिए, विभिन्न थ्रेड्स में एक ही सॉकेट से / भेजना / प्राप्त करना संभव है, ओएस सिंक्रनाइज़ेशन को संभाल लेगा।

हालाँकि, यदि भेजने / प्राप्त करने का क्रम शब्दगत रूप से महत्वपूर्ण है, तो आप स्वयं (क्रमशः आपका कोड) विभिन्न थ्रेड्स में संचालन के बीच उचित अनुक्रमण सुनिश्चित करना होगा - जैसा कि हमेशा थ्रेड्स के साथ होता है।


4

मैं नहीं देखता कि समानांतर में प्राप्त करना संभवतः कुछ भी पूरा कर सकता है। यदि आपके पास एक 3 बाइट्स संदेश है, तो 1 थ्रेड 1 2 बाइट्स और दूसरा अंतिम बाइट प्राप्त कर सकता है, लेकिन आपके पास यह बताने का कोई तरीका नहीं होगा कि कौन सा था। जब तक आपके संदेश केवल एक बाइट लंबे होते हैं, तब तक कोई तरीका नहीं है कि आप मज़बूती से कई थ्रेड प्राप्त करने के साथ कुछ भी काम कर सकें।

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

यदि कई थ्रेड भेजने की आवश्यकता है, तो आपको एक सिंक्रनाइज़ संदेश कतार को लागू करना चाहिए। एक सूत्र है कि वास्तविक भेजने कि कतार से संदेश पढ़ता है और अन्य धागे पूरे संदेश enqueue है। एक ही चीज़ प्राप्त करने के लिए काम करेगी, लेकिन प्राप्त थ्रेड को संदेशों के प्रारूप को जानना होगा, ताकि यह उन्हें उचित तरीके से निष्क्रिय कर सके।


9
यदि आप SOCK_DGRAM सॉकेट्स का उपयोग कर रहे हैं, तो प्रत्येक recv को एकल डेटाग्राम मिलेगा; यह recvs के बीच विभाजित नहीं किया जाएगा
क्रिस Dodd

2
@ कोई बात नहीं, मैं मानता हूं कि समानांतर रिकर्व कुछ भी पूरा नहीं कर सकता। इसलिए मैंने यह नहीं पूछा। मेरे प्रश्न को समानांतर रूप से भेजा / पुनरावृत्ति किया जाता है और फिर एकाधिक को समानता से भेजा जाता है। आपका उत्तर समानांतर भेजने में एक अंतर्दृष्टि देता है। उसी के लिए धन्यवाद।
Jay

1
@ अच्छी बात है। मैं टीसीपी मान रहा था। @ जय आप प्रश्न को स्पष्ट कर सकते हैं "क्या हम समानांतर रूप से प्राप्त करना चाहते हैं" जैसे हम भेज सकते हैं / फिर से बता सकते हैं "।
नूह
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.