Служба Boost Asio возвращается слишком рано - PullRequest
0 голосов
/ 22 ноября 2018

пытался решить эту проблему, с которой я столкнулся в отношении объекта io_service.Код, о котором идет речь, выглядит так:

    void connect_handler(const error_code &ec,iterator iterator){
        cout<<"Connect handler"<<endl;
    }

    void resolver_handler(const error_code &ec,iterator iterator,boost::asio::io_service &io){
        cout<<"Resolver handler..."<<endl;
        boost::asio::ip::tcp::socket socket(io);
        boost::asio::async_connect(socket,iterator,&connect_handler);
    }

    int main(){
        boost::asio::io_service io;
        resolver resolver(io);
        resolver::query query("example.com","http");
        resolver.async_resolve(query,boost::bind(resolver_handler,boost::asio::placeholders::error,boost::asio::placeholders::iterator,boost::ref(io)));
        cout<<io.run()<<endl;

        return 0;
    }

Попробовал то же самое в другом простом примере, когда все работает так, как задумано:

void printTwo(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
    cout<<"print two"<<endl;
}

void printOne(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
    cout<<"print one"<<endl;
    timer.async_wait(boost::bind(printTwo,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
}

int main(int argc, char** argv) {
    boost::asio::io_service io;
    boost::asio::deadline_timer timer(io,boost::posix_time::seconds(3));
    timer.async_wait(boost::bind(printOne,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
    cout<<io.run()<<endl;
    return 0;
}

Я предполагаю, что сервисный объект блокируется до тех пор, покаработа сделана;также поток, вызывающий функцию run, является потоком, из которого вызываются функции обработчика.Итак, почему второй блок кода работает так, как задумано, а не первый?заранее спасибо.

1 Ответ

0 голосов
/ 22 ноября 2018

io.run() в вашей программе вернется, как только io_service решит, что все сделано с работой, которую он должен выполнить.Это может произойти между операциями или, может быть, при вызове последнего асинхронного обратного вызова (я не совсем уверен).

Использование work объекта для информированияio_service для продолжения работы, и когда вы сбрасываете этот рабочий объект, вызов io_service run() должен возвращаться, как только он завершит выполнение любых ожидающих операций.

Основное использование - что-то вроде этого:

boost::asio::io_service io_service;
boost::asio::io_service::work work(io_service);
// ...
io_service.run(); // Blocks here

И обычно в другом потоке или, возможно, в одном из асинхронных обратных вызовов, вы делаете это:

work.reset();

И через некоторое время run() вернется.

...