2011-06-29 31 views
0

在下面的代码中,asynch_receive_from行为同步。在收到数据之前它不会回来。看看最后的日志表明这一点。这可能不是最初显而易见的,因为数据传入的速率相当高。但是当没有数据时,只有一秒钟的心跳消息,这些异步调用返回的时间也是一秒钟。boost:asio async_receive_from同步行为

问题是为什么这些异步调用不立即返回(在几个微秒内),并且没有读取字节?

我认为可能在运行队列中有其他项目会促进这个过程,认为如果队列上没有任何东西运行io_services会将异步函数变成同步函数,因为除此之外没有其他任何东西可以执行。但是我在异步调用之前添加了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

这是令人困惑的......它是“行为同步”,然后你会看到“1-Two”,“2-Two”和“3-Two”,然后看到“3”打印,显然不是案子。 – Chad

回答

2

不知道,如果你仍然有这个问题,但你打电话后io_service.run(它会阻止),因为它会一直寻找,它具有包接收。如果您希望它检查回调,但不阻止(如果没有),请使用io_service.poll()。如果您希望执行一次回调(如果有一个或多个请求),请使用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,那么这是真的吗? –