我应该从由resolver::async_resolve()调用的处理程序中调用socket::connect()吗?
我使用包装类来表示网络连接。我的实现包含一个名为 async_connect()
的方法,它解析主机/服务并连接到相关端点(如果可能)。像这样的事情:
void tcp::connection::async_connect(std::string const& host, std::string const& service,
protocol_type tcp = protocol_type::v4())
{
std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::async_connect()" << std::endl;
resolver(m_io_service).async_resolve(resolver::query(tcp, host, service),
boost::bind(&connection::resolve_handler, this, _1, _2));
}
我想要知道的是从处理程序建立连接,由 async_resolve 方法完成时调用。
我不确定是使用主线程还是工作线程来调用处理程序。因此,我应该调用 socket::connect()
(如果该代码从工作线程执行,这将是最明智的方法)还是再次启动异步操作 (socket:: async_connect() - 由主线程执行时应使用)。
void tcp::connection::resolve_handler(boost::system::error_code const& resolve_error,
tcp::resolver::iterator endpoint_iterator)
{
std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::resolve_handler()" << std::endl;
if (!resolve_error)
{
boost::system::error_code ec;
m_socket.connect(*endpoint_iterator, ec);
}
}
我从控制台输出观察到,我的 resolve_handler
是从工作线程调用的。那么,在这里调用 socket::connect()
可以吗?
I'm using a wrapper class to represent a network connection. My implementation contains a method, called async_connect()
, which resolves a host/service and connects to a related endpoint (if possible). Something like this:
void tcp::connection::async_connect(std::string const& host, std::string const& service,
protocol_type tcp = protocol_type::v4())
{
std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::async_connect()" << std::endl;
resolver(m_io_service).async_resolve(resolver::query(tcp, host, service),
boost::bind(&connection::resolve_handler, this, _1, _2));
}
What I want to do know, is establishing the connection from the handler, invoked by the completion of the async_resolve
method.
I'm not sure wheter the main thread or the a worker thread is used to invoke the handler. Thus, should I call socket::connect()
(this would be the most sensible way if that code would be executed from a worker thread) or start an asynchronous operation again (socket::async_connect()
- which should be used when executed by main thread).
void tcp::connection::resolve_handler(boost::system::error_code const& resolve_error,
tcp::resolver::iterator endpoint_iterator)
{
std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::resolve_handler()" << std::endl;
if (!resolve_error)
{
boost::system::error_code ec;
m_socket.connect(*endpoint_iterator, ec);
}
}
I've observed - from console output - that my resolve_handler
is called from a worker thread. So, is it okay to call socket::connect()
here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在我看来,使用 asio 时最好坚持单一编程模型。
您可以自由地使用 asio 的同步(阻塞)调用,您可以调用多种方法(解析、连接等),并且每个方法都会阻塞,直到结果或错误可用。
但是,如果您使用异步编程模型,您的主线程或调用线程通常会在 io_service::run 上阻塞,并且从不同的线程调用指定的处理程序(如您所描述的情况)。使用此编程模型时,您通常会从处理程序(工作线程)调用下一个async方法,因此您将调用socket::async_connect,而不是调用socket::connect。在我看来,您正在尝试混合两种不同的模型。我不确定混合两个模型(您的调用线程在 io_service::run 上被阻止)以及从处理程序调用同步方法会产生什么影响。
IMO it is good to stick to a single programming model when using asio.
You are free to use asio's synchronous (blocking) calls, where you call a number of methods (resolve, connect, etc) and each one blocks until the result or error is available.
However If you're using the asynchronous programming model, your main or calling thread is typically blocked on io_service::run and the specified handlers are called from a different thread ( as is the case in what you described). When using this programming model you would typically call the next async method from the handler (worker thread), so instead of calling socket::connect, you would call socket::async_connect. It looks to me like you are trying to mix the two different models. I'm not sure what the implications are of mixing the two models (with your calling thread blocked on io_service::run) and you calling a synchronous method from the handler.