2011-06-29 16 views
0

以下のコードでは、asynch_receive_fromは同期して動作します。データが受信されるまでは戻ってこない。最後のログを見るとこれが示されます。これは、かなり高いデータ転送速度があるため最初は明らかではない しかし、データがないときは、わずか1秒のハートビートメッセージが返されます。これらの非同期呼び出しからの復帰も1秒程度です。ブースト:asio async_receive_fromは同期的に動作します

なぜ、これらの非同期呼び出しが直ちに(数マイクロ以内で)返されず、バイトが読み取られないのですか?

私は実行キューに他のアイテムがあると思っていましたが、実行するキューに何もない場合、io_servicesはasynch関数をsynch関数に変えます。しかし、非同期呼び出しに先立って2つのポストを追加しました。私は、非同期呼び出しに先立って何かを実行キューに入れると信じています。しかし、それは違いを生むようには見えませんでした。

ご協力いただければ幸いです。私はboost :: asioライブラリが初めてです。あなたはまだこの問題を抱えている場合

void receiver::handle_receive_from(const boost::system::error_code& error, 
     size_t bytes_recvd) 
{ 
    static char logBuf[128];  
    string dStr; 
    int rVal; 
    unsigned int seqNo; 

    sprintf_s(logBuf, sizeof(logBuf), "BytesRead:%d", bytes_recvd); 
    MyLog(logBuf); 
    MyLog("1"); 
    MyLog("2"); 
    iosP->post(boost::bind(&receiver::postTestHandler, this)); 
    iosP->post(boost::bind(&receiver::postTestHandler, this)); 
    socket_.async_receive_from(
       boost::asio::buffer(data_, max_length), sender_endpoint_, 
       boost::bind(&receiver::handle_receive_fromTwo, this, 
       boost::asio::placeholders::error, 
       boost::asio::placeholders::bytes_transferred));  

    MyLog("3"); 

} 

void receiver::handle_receive_fromTwo(const boost::system::error_code& error, size_t bytes_recvd) 
{ 
    char logBuf[128]; 

    sprintf_s(logBuf, sizeof(logBuf), "Two BytesRead:%d", bytes_recvd); 
    MyLog(logBuf); 

    MyLog("1-Two"); 
    MyLog("2-Two"); 
    iosP->post(boost::bind(&receiver::postTestHandler, this)); 
    iosP->post(boost::bind(&receiver::postTestHandler, this)); 
    socket_.async_receive_from(
       boost::asio::buffer(data_, max_length), sender_endpoint_, 
       boost::bind(&receiver::handle_receive_from, this, 
       boost::asio::placeholders::error, 
       boost::asio::placeholders::bytes_transferred));   


    MyLog("3-Two"); 

} 

void receiver::postTestHandler() 
{ 
    int count(0); 
    MyLog("***postTestHandler entry***"); 
    printf("***postTestHandler entry***\n"); 
    printf("Exiting postTestHandler\n"); 
    MyLog("Exiting postTestHandler"); 
} 

ログは

[11:57:51.653647]BytesRead:16 
[11:57:51.653660]1 
[11:57:51.653662]2 
[11:57:51.653692]3 
[11:57:51.653697]***postTestHandler entry*** 
[11:57:51.654310]Exiting postTestHandler 
[11:57:51.654315]***postTestHandler entry*** 
[11:57:51.654657]Exiting postTestHandler 
[11:57:51.727494]Two BytesRead:67 
[11:57:51.727503]1-Two 
[11:57:51.727506]2-Two 
[11:57:51.727524]3-Two 
[11:57:51.727529]***postTestHandler entry*** 
[11:57:51.728060]Exiting postTestHandler 
[11:57:51.728065]***postTestHandler entry*** 
[11:57:51.728407]Exiting postTestHandler 
[11:57:52.438916]BytesRead:67 
[11:57:52.438929]1 
[11:57:52.438932]2 
[11:57:52.438961]3 
[11:57:52.438965]***postTestHandler entry*** 
[11:57:52.439568]Exiting postTestHandler 
[11:57:52.439573]***postTestHandler entry*** 
[11:57:52.439914]Exiting postTestHandler 
[11:57:52.581333]Two BytesRead:67 
[11:57:52.581346]1-Two 
[11:57:52.581349]2-Two 
[11:57:52.581375]3-Two 
[11:57:52.581381]***postTestHandler entry*** 
[11:57:52.582011]Exiting postTestHandler 
[11:57:52.582016]***postTestHandler entry*** 
[11:57:52.582358]Exiting postTestHandler 
[11:57:52.582364]BytesRead:67 
[11:57:52.582367]1 
[11:57:52.582370]2 
[11:57:52.582377]3 
[11:57:52.582381]***postTestHandler entry*** 
[11:57:52.582717]Exiting postTestHandler 
[11:57:52.582722]***postTestHandler entry*** 
[11:57:52.583055]Exiting postTestHandler 
[11:57:52.583061]Two BytesRead:67 
[11:57:52.583064]1-Two 
[11:57:52.583066]2-Two 
[11:57:52.583077]3-Two 
[11:57:52.583081]***postTestHandler entry*** 
[11:57:52.583418]Exiting postTestHandler 
[11:57:52.583423]***postTestHandler entry*** 
[11:57:52.583755]Exiting postTestHandler 
[11:57:52.616525]BytesRead:67 
[11:57:52.616531]1 
[11:57:52.616533]2 
[11:57:52.616549]3 
[11:57:52.616553]***postTestHandler entry*** 
[11:57:52.617015]Exiting postTestHandler 
[11:57:52.617020]***postTestHandler entry*** 
[11:57:52.617362]Exiting postTestHandler 
+0

今後、質問のコードを書式設定するのに時間をかけてください。他の人が読んで理解しやすくなります。 –

+0

あなたの質問は不明です。 'async_receive_from'は常に直ちに戻り、ある時点で完了ハンドラが呼び出されます。 –

+2

これは混乱しています...それは「同期的に動く」ということでしたが、 '3'が印刷される前に' 1-Two'、 '2-Two'、' 3-Two'が印刷されていました。ケース。 – Chad

答えて

2

わからないのスニペットが、あなたは(io_service.run呼び出した後、それは無限にそれを持っているパケットを探していますので、それは)ブロックします受け取った。コールバックをチェックし、何もない場合はブロックしないようにするには、io_service.poll()を使用します。ちょうど1つのコールバック(1つ以上のリクエストがある場合)を実行するには、io_service.poll_one()を使用します。

これがあなたの問題であるかどうか、またはこの問題がまだ残っているかどうかはわかりません(私はこの質問は非常に古いと思いますが)。 (あなたのコメントに応答して)

編集:

あなたがio_service.run()を使用している場合は、そのスレッドがASIOコールバックを扱うための永遠の専用となります。ただし、io_service.poll()を使用すると、その間に何か他のことをしたいときにコールバックを処理できます。 io_service.poll()はio_service.run()より速くはありません。いつでも無制限ではなく、いつでもコールバックを処理することができます。

あなたは、おそらくこのように実装されるように)(io_service.run画でした:それはこのように実装されていないことを

void IOService::run() 
{ 
    while (true) 
    { 
     poll(); 
    } 
} 

は注意してください。しかし、これは実行と投票が何をしているのかを明確にするかもしれない。

+0

これは将来役立ちます。だから、io_service.poll()やpoll_one()を使うとデータを読み込み、処理のために次のスレッドに移すより速い方法かもしれませんが、プロセスで多くのCPUを消費しますか? –