Wann muss ich die Verwendung von boost::asio:strand
Lesen das Dokument von boost::asio, es ist noch nicht klar, Wann muss ich die Verwendung von asio::Strang. Angenommen, ich habe einen thread mit io_service ist es dann sicher schreiben auf einen socket wie folgt ?
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;
}
}
}
Wo mehrere threads Aufrufe Anschluss::write(..) oder muss ich die Verwendung von asio::Strang ?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kurze Antwort: Nein, Sie müssen nicht auf eine
strand
in diesem Fall.Breit simplificated, ein
io_service
enthält eine Liste von function-Objekten (Handler). Handler werden in die Liste, wennpost()
genannt wird, auf den service. z.B. wenn eine asynchrone operation abgeschlossen ist, wird die Prozedur und die Argumente in der Liste.io_service::run()
führt ein Hundeführer nach dem anderen. Also, wenn es nur einen thread aufrufenrun()
wie in Ihrem Fall, es gibt keine Synchronisations-Probleme und keinestrand
s benötigt werden.Nur wenn mehrere threads rufen
run()
auf der gleichenio_service
mehrere Handler wird ausgeführt, zur gleichen Zeit, in der N threads bis zu N gleichzeitige Handler. Wenn das ein problem darstellt, z.B. ob es möglicherweise zwei Handler in die Warteschlange in der gleichen Zeit, die auf das gleiche Objekt, müssen Sie diestrand
.Sehen Sie die
strand
als eine Art Sperre für eine Gruppe von Handlern. Wenn ein thread einen handler zugeordnetstrand
, dassstrand
wird gesperrt, und es wird freigegeben, nachdem der handler fertig. Von einem anderen thread ausführen kann, nur-Handler, die nicht in Verbindung zu einem gesperrtenstrand
.Vorsicht: diese Erklärung möglicherweise zu vereinfacht und technisch nicht korrekt, aber es gibt ein grundlegendes Konzept von dem, was passiert in der
io_service
und derstrand
s.Aufrufen
io_service::run()
aus nur einem thread wird bewirken, dass alle event-Handler zum ausführen in den thread, unabhängig davon, wie viele threads aufrufenConnection::write(...)
. Daher, mit nicht möglich die gleichzeitige Ausführung der Prozeduren ist es sicher. Die Dokumentation bezieht sich auf diese als implizite Strang.Auf der anderen Seite, wenn mehrere threads aufrufen
io_service::run()
, dann einen Strang notwendig werden würden. Diese Antwort deckt Stränge in viel mehr detail.