को बढ़ावा देने ASIO लिखने लटका जब डिवाइस डिस्कनेक्ट

0

सवाल

मैं एक सर्वर अनुप्रयोग का उपयोग करता है कि को बढ़ावा देने ASIO संवाद करने के लिए कई ग्राहकों के साथ. सर्वर आवेदन पर चलाता है एक Linux सर्वर और क्लाइंट पर चलाने के लिए Windows डेस्कटॉप.

वर्तमान डिजाइन बहु लड़ी पिरोया हालांकि वहाँ केवल एक को बढ़ावा देने ASIO thead (जो चलाता है boost::asio::io_context). को बढ़ावा देने के ASIO धागे के लिए ही जिम्मेदार है, पढ़ने, लिखने, और कुछ निराला तक प्रेषण. पढ़ने का उपयोग किया जाता है boost::asio::async_read लेकिन प्रतियां जिसके परिणामस्वरूप संदेश इतना है कि एक धागे के काम कर सकते हैं प्रसंस्करण. लेखन का उपयोग किया जाता है boost::asio::write लेकिन संदेश पहले से ही किया गया है की नकल की और हाथ बंद करने के लिए बढ़ावा देने के ASIO धागा

अधिकांश परिस्थितियों में, जब एक क्लाइंट डिस्कनेक्ट बढ़ावा ASIO एक त्रुटि फेंकता है, मैं शट डाउन जुड़े, सॉकेट, और अन्य कुर्सियां रखने के लिए काम कर रहा है । लेकिन अगर एक ग्राहक के विंडोज डेस्कटॉप के लिए एक बिजली की विफलता है, जबकि boost::asio::write के लिए लिख रहा है तो उन्हें बढ़ावा नहीं करता है का पता लगाने के लिए एक मुद्दा है और में लटकी हुई है boost::asio::write. यह लटकी हुई है के लिए लगभग 20 मिनट के लिए कभी कभी और सर्वर संवाद नहीं कर सकता अन्य ग्राहकों के साथ इस समय के दौरान

से मैं क्या पढ़ा है, ऑनलाइन लेखकों को बढ़ावा देने के ASIO का कोई इरादा नहीं है शुरू करने के लिए एक मध्यांतर पैरामीटर । मैं स्थापित करने की कोशिश की SO_SNDTIMEO करने के लिए 5 सेकंड है, लेकिन नहीं था कि किसी को प्रभावित पर लिखने लटका. अब के रूप में मेरा सबसे अच्छा लगता है करने के लिए इस मुद्दे को हल करने के लिए है प्रत्येक सॉकेट एक अलग धागा इतना है कि एक ग्राहक नहीं कर सकते नीचे ले अन्य ग्राहकों. वहाँ किसी भी बेहतर विकल्प की तुलना में यह? अगर मैं दे हर सॉकेट अपने स्वयं के धागे करता है कि मतलब है कि मैं एक की आवश्यकता होगी boost::asio::io_context प्रति धागे से बचने के लिए लिखने लटका?

संपादित करें: देखने के बाद टिप्पणी की कोशिश की redoing कि समारोह कॉल boost::asio::write के साथ boost::asio::async_write. नीचे मैं कुछ कोड है कि सरलीकृत किया गया था के लिए तो, लेकिन अभी भी पता चलता है क्या के समग्र परिवर्तन किया गया था:

मूल रूप से के साथ boost::asio::write:

inline void MessagingServer::writeMessage(
    GuiSession* const  a_guiSession,
    const PB::Message& a_msg
) {
    boost::asio::dispatch(m_guiIoIoContext, [this, a_guiSession, a_msg]() {
        // I removed code that writes a_msg's bytes into m_guiIoWriteBuf
        // and sets totalSize to simplify for SO

        boost::system::error_code error;
        boost::asio::write(a_guiSession->m_guiIoGsSocket, boost::asio::buffer(m_guiIoWriteBuf, totalSize), error);
        if (UNLIKELY(error))
            ERRLOG << a_guiSession->m_gsSessionId << " write failed: " << error.message();
    });
}

Redone के साथ boost::asio::async_write:

inline void MessagingServer::writeMessage(
    GuiSession* const  a_guiSession,
    const PB::Message& a_msg
) {
    a_guiSession->m_tempMutex.lock();

    boost::asio::dispatch(m_guiIoIoContext, [this, a_guiSession, a_msg]() {
        // I removed code that writes a_msg's bytes into m_guiIoWriteBuf
        // and sets totalSize to simplify for SO

        boost::asio::async_write(
            a_guiSession->m_guiIoGsSocket,
            boost::asio::buffer(m_guiIoWriteBuf, totalSize),
            [this, a_guiSession](const boost::system::error_code& a_error, std::size_t) {
                if (UNLIKELY(a_error))
                    ERRLOG << a_guiSession->m_gsSessionId << " write failed: " << a_error.message();

                a_guiSession->m_tempMutex.unlock();
            }
        );
    });
}

ताला में पेश किया गया था दूसरी कोड की गारंटी करने के लिए केवल एक ही कॉल करने के लिए boost::asio::async_write सक्रिय था पर एक समय (मैं जानता हूँ कि वहाँ रहे हैं और अधिक performant तरीके से ऐसा करने के लिए, लेकिन यह आसान है के लिए परीक्षण). इन दोनों के कोड है एक ही मुद्दे की फांसी को बढ़ावा देने ASIO जब ग्राहक एक बिजली की विफलता. हालांकि वे लटका है, अलग अलग तरीकों से अतुल्यकालिक कोड की अनुमति देता है को बढ़ावा देने के लिए ASIO करने के लिए अन्य कार्यों प्रदर्शन नहीं है, बस आगे लिखते हैं जब तक फांसी से एक पैदा करता है, एक त्रुटि

के दौरान एक अलग प्रयोग मैंने किया था स्थापित करने की कोशिश करो SO_KEEPALIVE लेकिन जो भी समाधान नहीं किया फांसी का मुद्दा

asio boost c++ multithreading
2021-11-22 19:46:12
1

सबसे अच्छा जवाब

1

मैं सहमत हूं साथ टिप्पणीकर्ताओं है कि यह कैसे TCP आम तौर पर काम करता है.

ध्यान दें कि आप लागू कर सकते हैं समय समाप्ति का उपयोग कर एक ASIO टाइमर की अनुमति है, जो रद्द करने के लिए आप aynchronous के संचालन पर अपनी कुर्सियां.

वहाँ रहे हैं कई कई उदाहरण हैं, यदि आप खोज के लिए

  • को बढ़ावा देने::asio::steady_timer, oost::asio::high_resolution_timer और अनुरूप के सदस्यों एसटीडी::chrono परिवार की घड़ियों
  • को बढ़ावा देने::deadline_timer
2021-11-22 22:29:35

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में