问题描述
阅读的boost :: ASIO的文件,它仍然是不明确的,当我需要使用ASIO ::链。假设我有一个线程使用io_service对象就是它,然后安全套接字上写如下?
无效连接::写(提高:: shared_ptr的<串GT; MSG)
{
_io_service.post(升压::绑定(安培;连接:: _ do_write,对此,味精));
}无效连接:: _ do_write(提升:: shared_ptr的<串GT; MSG)
{
如果(_write_in_progress)
{
_msg_queue.push_back(MSG);
}
其他
{
_write_in_progress = TRUE;
提高:: ASIO :: async_write(_socket,提高:: ASIO ::缓冲区(*(msg.get()))
提高::绑定(安培;连接:: _ handle_write,为此,
提高:: ASIO ::占位符::错误));
}
}无效连接:: _ handle_write(的boost ::系统::错误_ code常量和放大器;错误)
{
如果(!错误)
{
如果(!_ msg_queue.empty())
{
提高:: shared_ptr的<串GT;味精= _msg_queue.front();
_msg_queue.pop_front();
提高:: ASIO :: async_write(_socket,提高:: ASIO ::缓冲区(*(msg.get()))
提高::绑定(安培;连接:: _ handle_write,为此,
提高:: ASIO ::占位符::错误));
}
其他
{
_write_in_progress = FALSE;
}
}
}
在多个线程调用连接::写(..)或者我必须使用ASIO ::链?
简短的回答:不,你没有在这种情况下,使用链
。 p>
从广义simplificated,一个 io_service对象
包含函数对象(句柄)的列表。处理程序被放入列表时,后()
上调用该服务。例如每当一个异步操作完成,处理程序和它的参数放入列表中。 :: io_service对象的run()
陆续执行一个处理程序。因此,如果只有一个线程调用的run()
像你的情况,有没有同步的问题,也没有链
需要秒。结果
只有当多个线程调用的run()
在同一个 io_service对象
,多个处理程序将在同一时间执行,在N个线程直到N并发处理程序。如果这是一个问题,例如如果有可能是在排队两个处理程序在访问同一个对象的同时,你需要的链
。结果
你可以看到链
作为一种锁一组处理程序。如果一个线程执行关联到一个处理程序链
,即链
被锁定,它被释放之后的处理程序完成。任何其他线程可以执行只有那些没有关联的处理程序锁定链
。
注意:的这个解释可能是过于简单和技术上的不准确的,但它给在 io_service对象和的
链
。
Reading the document of boost::asio, it is still not clear when I need to use asio::strand. Suppose that I have one thread using io_service is it then safe to write on a socket as follows ?
void Connection::write(boost::shared_ptr<string> msg)
{
_io_service.post(boost::bind(&Connection::_do_write,this,msg));
}
void Connection::_do_write(boost::shared_ptr<string> msg)
{
if(_write_in_progress)
{
_msg_queue.push_back(msg);
}
else
{
_write_in_progress=true;
boost::asio::async_write(_socket, boost::asio::buffer(*(msg.get())),
boost::bind(&Connection::_handle_write,this,
boost::asio::placeholders::error));
}
}
void Connection::_handle_write(boost::system::error_code const &error)
{
if(!error)
{
if(!_msg_queue.empty())
{
boost::shared_ptr<string> msg=_msg_queue.front();
_msg_queue.pop_front();
boost::asio::async_write(_socket, boost::asio::buffer(*(msg.get())),
boost::bind(&Connection::_handle_write,this,
boost::asio::placeholders::error));
}
else
{
_write_in_progress=false;
}
}
}
Where multiple threads calls Connection::write(..) or do I have to use asio::strand ?
Short answer: no, you don't have to use a strand
in this case.
Broadly simplificated, an io_service
contains a list of function objects (handlers). Handlers are put into the list when post()
is called on the service. e.g. whenever an asynchronous operation completes, the handler and its arguments are put into the list. io_service::run()
executes one handler after another. So if there is only one thread calling run()
like in your case, there are no synchronisation problems and no strand
s are needed.
Only if multiple threads call run()
on the same io_service
, multiple handlers will be executed at the same time, in N threads up to N concurrent handlers. If that is a problem, e.g. if there might be two handlers in the queue at the same time that access the same object, you need the strand
.
You can see the strand
as a kind of lock for a group of handlers. If a thread executes a handler associated to a strand
, that strand
gets locked, and it gets released after the handler is done. Any other thread can execute only handlers that are not associated to a locked strand
.
Caution: this explanation may be over-simplified and technically not accurate, but it gives a basic concept of what happens in the io_service
and of the strand
s.
这篇关于我什么时候使用boost :: ASIO:股的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!