繁体   English   中英

boost:asio async_receive_from 行为同步

[英]boost:asio async_receive_from behaves synchronously

在下面的代码中, asynch_receive_from 的行为是同步的。 在收到数据之前它不会回来。 查看最后的日志表明了这一点。 这可能一开始并不那么明显,因为有相当高的数据进入率。但是当没有数据时,只有一秒钟的心跳消息,这些异步调用的返回也是大约一秒钟。

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

我认为在运行队列中可能有其他项目会促进该过程,认为如果队列中没有任何内容可以运行,那么 io_services 会将异步 function 转换为同步 function ,因为它没有其他事情要做。 但是我在异步调用之前添加了 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

不确定您是否仍然遇到此问题,但在您调用 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();
    }
}

请注意,它不是这样实现的。 但这可能会澄清 run 和 poll 正在做什么的想法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM