Verwirrt, wenn boost :: asio :: io_service Methodenblöcke ausführt / entsperrt
Als absoluter Anfänger von Boost.Asio bin ich verwirrt mitio_service::run()
. Ich würde mich freuen, wenn mir jemand erklären könnte, wann diese Methode blockiert / entsperrt. In den Dokumentationen heißt es:
Dasrun()
Funktionsblöcke, bis alle Arbeiten abgeschlossen sind und keine Handler mehr zu versenden sind, oder bisio_service
wurde gestoppt.
Mehrere Threads können das aufrufenrun()
Funktion, um einen Pool von Threads einzurichten, aus denen dieio_service
darf Handler ausführen. Alle Threads, die im Pool warten, sind gleich und dieio_service
kann einen beliebigen von ihnen auswählen, um einen Handler aufzurufen.
Ein normaler Ausstieg aus demrun()
Funktion impliziert, dass dieio_service
Objekt ist gestoppt (dasstopped()
Funktion liefert true zurück). Nachfolgende Anrufe anrun()
, run_one()
, poll()
oderpoll_one()
wird sofort zurückkehren, es sei denn, es liegt ein vorheriger Anruf beireset()
.
Was bedeutet die folgende Aussage?
[...] keine Handler mehr zum Versand [...]
Beim Versuch, das Verhalten von zu verstehenio_service::run()
Ich bin darauf gestoßenBeispiel (Beispiel 3a). Darin beobachte ich dasio_service->run()
blockiert und wartet auf Arbeitsaufträge.
// WorkerThread invines io_service->run()
void WorkerThread(boost::shared_ptr<boost::asio::io_service> io_service);
void CalculateFib(size_t);
boost::shared_ptr<boost::asio::io_service> io_service(
new boost::asio::io_service);
boost::shared_ptr<boost::asio::io_service::work> work(
new boost::asio::io_service::work(*io_service));
// ...
boost::thread_group worker_threads;
for(int x = 0; x < 2; ++x)
{
worker_threads.create_thread(boost::bind(&WorkerThread, io_service));
}
io_service->post( boost::bind(CalculateFib, 3));
io_service->post( boost::bind(CalculateFib, 4));
io_service->post( boost::bind(CalculateFib, 5));
work.reset();
worker_threads.join_all();
In dem folgenden Code, an dem ich gearbeitet habe, stellt der Client jedoch eine Verbindung über TCP / IP her, und die Ausführungsmethode wird blockiert, bis Daten asynchron empfangen werden.
typedef boost::asio::ip::tcp tcp;
boost::shared_ptr<boost::asio::io_service> io_service(
new boost::asio::io_service);
boost::shared_ptr<tcp::socket> socket(new tcp::socket(*io_service));
// Connect to 127.0.0.1:9100.
tcp::resolver resolver(*io_service);
tcp::resolver::query query("127.0.0.1",
boost::lexical_cast< std::string >(9100));
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
socket->connect(endpoint_iterator->endpoint());
// Just blocks here until a message is received.
socket->async_receive(boost::asio::buffer(buf_client, 3000), 0,
ClientReceiveEvent);
io_service->run();
// Write response.
boost::system::error_code ignored_error;
std::cout << "Sending message \n";
boost::asio::write(*socket, boost::asio::buffer("some data"), ignored_error);
Jede Erklärung vonrun()
Das beschreibt sein Verhalten in den beiden folgenden Beispielen.