Zdezorientowany, gdy boost :: asio :: io_service uruchamia metodę blokuje / odblokowuje
Będąc całkowicie początkującym do Boost.Asio, jestem zdezorientowanyio_service::run()
. Byłbym wdzięczny, gdyby ktoś mógł mi wyjaśnić, kiedy ta metoda blokuje / odblokowuje. Dokumentacja stwierdza:
Therun()
bloki funkcyjne, dopóki cała praca nie zostanie zakończona i nie będzie już więcej programów obsługi do wysłania lub do czasuio_service
został zatrzymany.
Wiele wątków może wywoływaćrun()
funkcja, aby ustawić pulę wątków, z którychio_service
może wykonywać programy obsługi. Wszystkie wątki oczekujące w puli są równoważne iio_service
może wybrać dowolną z nich, aby wywołać obsługę.
Normalne wyjście zrun()
funkcja sugeruje, żeio_service
obiekt jest zatrzymany (stopped()
funkcja zwraca true). Kolejne wywołania dorun()
, run_one()
, poll()
lubpoll_one()
wróci natychmiast, chyba że nastąpi wcześniejsze połączeniereset()
.
Co oznacza poniższe stwierdzenie?
[...] nie ma więcej handlerów do wysłania [...]
Próbując zrozumieć zachowanieio_service::run()
, Natknąłem się na toprzykład (przykład 3a). W nim obserwuję toio_service->run()
blokuje i czeka na zlecenia pracy.
// 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();
Jednak w poniższym kodzie, nad którym pracowałem, klient łączy się za pomocą protokołu TCP / IP i bloków metody uruchamiania, dopóki dane nie zostaną asynchronicznie odebrane.
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);
Wszelkie wyjaśnieniarun()
to opisuje jego zachowanie w dwóch poniższych przykładach.