मैं देख रहा हूँ Asio Blocking को बढ़ावा दें TCP क्लाइंट टाइमआउट एक विशेष रुचि के साथ उदाहरण है कि कनेक्शन टाइमआउट कैसे लागू किया जाता है। हम दस्तावेज़ीकरण से कैसे जानते हैं कि कॉलबैक हैंडलर और बाद के चेक दौड़ की स्थिति पेश नहीं करते हैं?

अतुल्यकालिक कनेक्शन कमांड

boost::asio::async_connect(socket_, iter, var(ec) = _1);

var(ec) = _1 को निष्पादित करता है जो एक बार निष्पादित होने पर त्रुटि कोड सेट करने के लिए हैंडलर है। वैकल्पिक रूप से, यहां एक पूर्ण और स्पष्ट लैम्ब्डा का उपयोग किया जा सकता है।

उसी समय, check_deadline फ़ंक्शन प्रतीत होता है deadline_ सदस्य द्वारा बुलाया गया। टाइमआउट को समय सीमा को जबरन सॉकेट बंद करके लागू किया गया प्रतीत होता है, जहां हम मानते हैं कि शायद अवरुद्ध कथन

do io_service_.run_one(); while (ec == boost::asio::error::would_block);

लौटेंगे। पहले तो मैंने सोचा कि त्रुटि कोड परमाणु होना चाहिए लेकिन ऐसा प्रतीत नहीं होता है। इसके बजाय, यह पेज , यह इंगित करता प्रतीत होता है कि जब भी सॉकेट/संदर्भ में कॉल एक ही थ्रेड से आती है तो स्ट्रैंड मॉडल काम करेगा।

इसलिए हम मानते हैं कि समय सीमा के लिए प्रत्येक कॉलबैक (जो कि Asio में है) और async_connect रूटीन के लिए हैंडल एक साथ नहीं चलाए जाएंगे। पेज जैसे यह दस्तावेज़ीकरण संकेत में कि हैंडलर केवल run() कॉल के दौरान निष्पादित करेंगे जो वर्तमान में इसके मूल्य को बदलने वाले हैंडलर के दौरान निष्पादित while(ec == whatever) कमांड को पीछे से रोक देगा।

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

मुझे जो बंद मिले हैं, वे हैं दस्तावेज़ीकरण io_context कहावत

I/O ऑब्जेक्ट्स पर सिंक्रोनस ऑपरेशंस व्यक्तिगत ऑपरेशन के लिए io_context ऑब्जेक्ट को परोक्ष रूप से चलाते हैं। io_context फ़ंक्शन run(), run_one(), run_for(), run_until(), poll() या poll_one() को io_context के लिए C++ प्रोग्राम की ओर से अतुल्यकालिक संचालन करने के लिए कॉल किया जाना चाहिए। अधिसूचना कि एक एसिंक्रोनस ऑपरेशन पूरा हो गया है, संबंधित हैंडलर के आह्वान द्वारा वितरित किया जाता है। हैंडलर को केवल एक थ्रेड द्वारा आमंत्रित किया जाता है जो वर्तमान में io_context के लिए रन (), रन_ऑन (), रन_फॉर (), रन_अनटिल (), पोल () या पोल_ऑन () के किसी भी अधिभार को कॉल कर रहा है।

इसका तात्पर्य यह है कि यदि मेरे पास run_one() कमांड चलाने वाला एक थ्रेड है तो उसका नियंत्रण पथ तब तक प्रतीक्षा करेगा जब तक कि एक हैंडलर उपलब्ध न हो और अंततः एक हैंडलर के माध्यम से अपना रास्ता घुमाए जहां वह वापस आ जाएगा और ec मान की जांच करेगा।

क्या यह सही है और "हैंडलर को केवल एक थ्रेड द्वारा आमंत्रित किया जाता है जो वर्तमान में io_context के लिए रन (), रन_ऑन (), रन_फॉर (), रन_अनटिल (), पोल () या पोल_ऑन () के किसी भी अधिभार को कॉल कर रहा है। यह समझने के लिए सबसे अच्छा कथन है कि कोड हमेशा कैसे कार्य करेगा? क्या कोई अन्य प्रदर्शनी है?

1
Steve 2 अगस्त 2020, 00:01

1 उत्तर

सबसे बढ़िया उत्तर

Asio लाइब्रेरी नेटवर्किंगटीएस के रूप में मानकीकृत होने के लिए तैयार है। यह हिस्सा वास्तव में सौदा है:

हैंडलर को केवल एक थ्रेड द्वारा बुलाया जाता है जो वर्तमान में io_context के लिए रन (), रन_ऑन (), रन_फॉर (), रन_अनटिल (), पोल () या पोल_ऑन () के किसी भी अधिभार को कॉल कर रहा है।

आप यह निष्कर्ष निकालने में सही हैं कि पूरा उदाहरण 100% सिंगल-थ्रेडेड है। दौड़ नहीं हो सकती।

मुझे व्यक्तिगत रूप से सबसे अच्छा संसाधन लगता है थ्रेड्स और Boost.Asio पेज:

  • केवल एक थ्रेड से io_context::run() को कॉल करके, उपयोगकर्ता का कोड सिंक्रोनाइज़ेशन से जुड़ी विकास जटिलता से बच सकता है। उदाहरण के लिए, एक पुस्तकालय उपयोगकर्ता एकल-थ्रेडेड (उपयोगकर्ता के दृष्टिकोण से) स्केलेबल सर्वर को लागू कर सकता है।

यह पहले की सच्चाई को भी दोहराता है:

[...] निम्नलिखित गारंटी:

  • एसिंक्रोनस पूर्णता हैंडलर को केवल उन थ्रेड्स से बुलाया जाएगा जो वर्तमान में io_context::run() को कॉल कर रहे हैं।

प्लेटफ़ॉर्म/एक्सटेंशन के आधार पर संभावित आंतरिक सेवा थ्रेड को छोड़कर, थ्रेड्स पृष्ठ विवरण

1
sehe 1 अगस्त 2020, 23:15