Будучи полным новичком в Boost.Asio, меня путают с io_service::run()
. Я был бы признателен, если бы кто-нибудь мог объяснить мне, когда этот метод блокирует/разблокирует. В документах указано:
Функциональные блоки
run()
блокируются до тех пор, пока все работы не будут завершены, и больше обработчиков не будет отправлено или пока не будет остановленio_service
.Несколько потоков могут вызывать функцию
run()
для настройки пула потоков, из которыхio_service
может выполнять обработчики. Все потоки, ожидающие в пуле, эквивалентны, аio_service
может выбрать любой из них для вызова обработчика.Нормальный выход из функции
run()
означает, что объектio_service
остановлен (функцияstopped()
возвращает true). Последующие вызовыrun()
,run_one()
,poll()
илиpoll_one()
будут немедленно возвращены, если не был предыдущий вызовreset()
.
Что означает следующее выражение?
[...] больше обработчиков не будет отправлено [...]
При попытке понять поведение io_service::run()
я столкнулся с этим примером (пример 3a). Внутри него я замечаю, что io_service->run()
блокирует и ждет рабочих заказов.
// 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();
Однако в следующем коде, над которым я работал, клиент соединяется с использованием TCP/IP и блоков метода выполнения, пока данные не будут асинхронно приняты.
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);
Любое объяснение run()
, описывающее его поведение в двух приведенных ниже примерах, будет оценено.