![](/img/trans.png)
[英]interrupting boost::asio::async_receive_from from another thread
[英]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.