เพิ่ม ASIO เขียนแขวนคอเมื่ออุปกรณ์ disconnects

0

คำถาม

ฉันต้องเซิร์ฟเวอร์โปรแกรมที่ใช้เพิ่ม ASIO ต้องติดต่อกับหลายรายชื่อรั่วไหลออก เซิร์ฟเวอร์โปรแกรมวิ่งอยู่บนระบบลินุกซ์เซิร์ฟเวอร์และพวกลูกค้าประมวลผลเมื่อหน้าต่างบนพื้นที่ทำงาน.

ปัจจุบันออกแบบเป็นหลาย threaded ถึงแม้ว่ามันมีแค่คนเดียวที่เพิ่ม ASIO thead(ซึ่งวิ่ง boost::asio::io_context). ที่เพิ่ม ASIO เธรดเป็นเพียงรับผิดชอบอ่านหนังสือเขียนและบาง infrequent กรุณาฝากข้อความ อ่านเสร็จแล้วใช้ boost::asio::async_read แต่สำเนานผลลัพธ์จากข้อความนั่นอีกด้าสามารถทำงานการประมวณผลนี้ เขียนเสร็จแล้วใช้ boost::asio::write แต่ข้อความที่ได้คัดลอกและส่งออกไปที่เพิ่ม ASIO เธรด

ภายใต้สถานการณ์ส่วนใหญ่เมื่อเป็นลูกค้าของ disconnects เพิ่ม ASIO ให้เกิดข้อผิดพลาดเกิดขึ้นระหว่างฉันปิดที่เกี่ยวข้องซ็อกเก็ตและคนอื่นซ็อกเกตอทำงานต่อไป แต่ถ้าเป็นลูกค้าของหน้าต่างบนพื้นที่ทำงานมีพลังงานล้มเหลวขณะ boost::asio::write คือการเขียนกับพวกเขางั้นเพิ่มไม่ได้ตรวจจับเป็นปัญหาและนั้นแขวนอยู่บ boost::asio::write. มันแกร่วอยู่มาเกือบ 20 นาทีบางครั้งแล้วโดยเซิร์ฟเวอร์ไม่สามารถสื่อสารกับลูกค้าระหว่างเวลานี้

จากสิ่งที่ฉันต้องอ่านออนไลน์นผู้เขียนเพิ่ม ASIO ไม่มีความตั้งใจขอแนะนำผู้หมดเวลาพารามิเตอร์. ฉันพยายามการตั้งค่า SO_SNDTIMEO ต้อง 5 วินาทีแต่นั่นมันไม่มีผลกระทบต่อที่เขียนเที่ยวด้วยกัน ตอนนี้ดีที่สุดของฉันเดาว่าต้องแก้ปัญหาคือต้องให้ทุกซ็อกเกตได้อีกด้าดังนั้นลูกค้าคนหนึ่งไม่สามารถไปลงที่ลูกค้าอีกคน มีอะไรดีขึ้นตัวเลือกมากกว่านี้? ถ้าฉันทำให้ทุกซ็อกเก็ตของเธรดมันหมายความว่าฉันจะต้องการ boost::asio::io_context ต่อเธรดที่จะหลีกเลี่ยงการเขียนแขวนคอ?

แก้ไข:หลังจากเห็นคอมเมนท์ฉันพยายามเรียนซ้ำฟังก์ชันที่โทรมา boost::asio::write กับ boost::asio::async_write. ด้านล่างนี้ฉันต้องมีรหัสนั่นเป็นประยุกต์@item text character set สำหรับดังนั้นแต่ยังคงแสดงอะไรทั้งหมดนี้เปลี่ยนเป็น:

ในตอนแรงกับ 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 ตอนที่ลูกค้าของมีพลังความล้มเหลว แต่พวกเขาแขวนคออยู่ในวิธีที่แตกต่างกันที่ asynchronous รหัสมันออนุญาตให้สำหรับเพิ่ม ASIO ต้องแสดงการกระทำอื่นๆก็ไม่ได้ต่อเขียนจนถึงแขวนหนึ่งได้เกิดข้อผิดพลาด

ระหว่างการทดลองแยกกันฉันพยายามการตั้งค่า SO_KEEPALIVE แต่นั่นก็ไม่ได้แก้ปัญหาแขวนปัญหา

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

คำตอบที่ดีที่สุด

1

ฉันเห็นด้วยกับคน commenters ว่านี่คือวิธี TCP โดยทั่วไปทำงาน

โปรดจำไว้ว่าคุณสามารถแนะนำ timeouts ใช้ 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ý
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่