2017-08-29 32 views
0

我正在編寫一個程序,該程序將讀取的數據轉發給另一個對等設備。 我有一個方法,在每次讀取套接字上的數據後被調用。此方法將數據發佈到一個鏈中,以將其寫回另一個對等體。發送大塊數據時,應用程序發回的數據與收到的數據不一樣,問題是數據不再有序。這只是在boost :: asio :: io_service中使用多個線程的情況。即使在使用strand時,async_writes的排序也不正確

handleGatewayReply在某些數據在套接字上讀取時調用。 在這裏(1),在將數據寫入文件後,我可以看到數據仍然是有序的。 之後,postBackendReply被調用,數據仍然是有序的(2)。 但是在SessionConnection :: postReply中,如果我將數據刷新到文件(3),我可以看到數據不再被排序。 我看不出爲什麼訂單在此時丟失了,我試圖在handleGatewayReply和postBackendReply中使用一個鏈(如代碼所示),但行爲仍然相同。

對不起,我無法提交最小化,完整和可驗證的示例,因爲該錯誤太難以發現,需要多線程轉發大量數據。

void Reply::handleGatewayReply(std::stringstream* stream) 
    { 
    // Flush data to file (1) 
    m_strand.post(std::bind([=]() { 
     postBackendReply(*stream); 
     delete stream; 
    } 
    })); 

    } 

void Reply::postBackendReply(const std::stringstream& stream) 
    { 
    auto buffer = std::make_shared<Buffer>(); 
    buffer->m_buffers.push_back(stream.str()); 
    // Flush data to file (2) 
    auto connection = m_request->connection(); 
    if (connection) { 
// connection->postReply(buffer); // doesn't work either 
      m_strand.post(std::bind(&SessionConnection::postReply, connection,buffer)); 
    } 

    } 


    void SessionConnection::postReply(BufferPtr buffer) 
    { 
     // Flush data to file (3) 
     m_ioService.post(
     m_ostrand.wrap(
      std::bind(&SessionConnection::sendNext, 
        shared_from_this(), buffer))); 
    } 
    } 

回答

4

當使用鏈:

  1. 從來沒有發佈任何處理直接到io_service - 這是保證失去訂貨和突破並行的保證。

  2. strand::wrap每個異步處理程序。

  3. 在(包裹)處理程序中,如果您需要強制命令,dispatch來鏈。如果發佈的處理程序在將來的某個時刻執行時仍然有效,則只有post

例如:

thing.async_op(mystrand.wrap([self = shared_from_this()](auto&& error){ 
    self->mystrand.dispatch(&must_be_done_now_A); 
    self->mystrand.post(&may_be_done_out_of_order_B); 
    self->mystrand.dispatch(&must_be_done_now_C); 
}); 

執行順序是:

  1. thing的處理程序
  2. must_be_done_now_A
  3. must_be_done_now_C
  4. thing的處理程序完成
  5. 在此期間
  6. may_be_done_out_of_order_B
+0

1.我從來沒有直接張貼處理程序io_service對象鑽進io_service任何其他的東西,我總是用鏈 2.每async_write處理程序已被包裝在一個鏈中 3.我試圖用調度來替換該文章,但同樣的問題。任何其他想法?爲什麼它在回覆:: postBackendReply中訂購(所以這裏沒有問題的訂單),但不是在postReply?這裏會發生什麼? –

+0

@BenD如果你不包裝你的處理程序,所有的訂購都是運氣。 –

+0

@BenD在你的函數'postReply'中,你實際上發佈了一篇文章。訂單已不再保證。 –

相關問題