Я изучаю многопоточность и библиотеки Boost (в частности, Asio), и мне трудно понять, как работает следующий код (немного измененный из учебных пособий Boost.org)
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
class printer
{
public:
printer(boost::asio::io_service& io)
: timer1_(io, boost::posix_time::seconds(1)),
timer2_(io, boost::posix_time::seconds(1)),
count_(0)
{
timer1_.async_wait(boost::bind(&printer::print1, this));
timer2_.async_wait(boost::bind(&printer::print2, this));
}
~printer()
{
std::cout << "Final count is " << count_ << std::endl;
}
void print1()
{
if (count_ < 10)
{
std::cout << "Timer 1: " << count_ << std::endl;
++count_;
timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(2));
timer1_.async_wait(boost::bind(&printer::print1, this));
}
}
void print2()
{
if (count_ < 10)
{
std::cout << "Timer 2: " << count_ << std::endl;
++count_;
timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(2));
timer2_.async_wait(boost::bind(&printer::print2, this));
}
}
private:
boost::asio::deadline_timer timer1_;
boost::asio::deadline_timer timer2_;
int count_;
};
void saysomething()
{
std::string whatyasay;
std::cin >> whatyasay;
std::cout << "You said " << whatyasay << std::endl;
}
int main()
{
boost::asio::io_service io;
printer p(io);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
io.run();
std::cout << "Hey there\n";
t.join();
return 0;
}
Какие результаты в следующем выводе
Timer 1: 0
Timer 2: 1
Timer 1: 2
Timer 2: 3
Timer 1: 4
Timer 2: 5
Timer 1: 6
Timer 2: 7
Timer 1: 8
Timer 2: 9
Hey there
Final count is 10
Я ожидал от этого кода , что поток t будет отвечать за запуск io_service, что означает, что другие операции могут выполняться в То время.
Вместо код работает как обычно, aka, io.run «блокирует» поток кода до тех пор, пока таймеры внутри объекта принтера не прекратят запуск async_waits, поэтому «эй там» выводится только на печать после того, как таймеры больше не работают.
Но это еще не все: насколько я понимаю, io_services не прекращает работу после вызова метода run (), пока с ним связана работа (будь то работа) объект или, в данном случае, таймеры). С учетом вышесказанного, поскольку поток связан с io_service, мне интересно, почему io_service вообще перестал работать: в конце концов, поток «связан» с io_service и продолжает работать самостоятельно; это, очевидно, связано с тем фактом, что я явно не понимал, что этот поток делает в первую очередь.
Ситуация стала еще сложнее, когда я добавил метод "sayomething" в банк: я хотел быть в состоянии написать что-то и печатать эту строку, пока 2 таймера продолжали работать. Код, который я использовал, был следующий:
int main()
{
boost::asio::io_service io;
printer p(io);
boost::thread t(&saysomething);
io.run();
std::cout << "Hey there\n";
t.join();
return 0;
}
со следующим результатом:
Timer 1: 0
Timer 2: 1
Timer 1: 2
Timer 2: 3
Timer 1: 4
Timer 2: 5
Timer 1: 6
Timer 2: 7
ghg //<--- my input
You said ghg
Timer 1: 8
Timer 2: 9
Hey there
Final count is 10
Он работает нормально, но теперь, когда нет никакого потока, связанного с io_service, что было его Во-первых, цель?
Подводя итог, я задаю 3 вопроса:
- Почему строка «Hey there» не выводится сразу, а не ожидает остановки работы io_service ?
- Как именно io_service перестает работать, если с ним связан поток, что должно быть эквивалентно io_service, выполняющему работу?
- Так как поток не разрешал "код" поток ", чтобы двигаться вперед, и связывание указанного потока с моим методом вместо io_service не вызвало никакой ошибки, какова была цель этого потока с самого начала?