boost :: asio :: io_service :: run () не завершается, когда я вызываю boost :: asio :: io_serive :: stop () - PullRequest
0 голосов
/ 27 декабря 2011

Привет, я написал одно простое приложение, которое использует асинхронные функции сокетов.Я сталкиваюсь с некоторыми проблемами при закрытии сокета.

Я использую 5-секундный таймер перед вызовом async_connect на сокете.В некоторых случаях соединение не происходит, и таймер истекает.Когда таймер истекает, я закрываю сокет tcp_socket.close().Но дело в том, что мой обработчик обратного вызова соединения вообще не вызывается с ошибкой boost::asio::error::operation_aborted, когда я пытался отменить вместо закрытия.То же самое происходит и для следующих всех асинхронных подключений.

Событие, хотя я закрываю сокет tcp и уничтожаю объект client_session, вызов join () для созданного потока не происходит, значит io_service :: run () все еще работает не выходя ... :-( Я не знаю, почему это происходит ... пробовал много других способов, все еще сталкиваясь с той же проблемой.

Я не понимаю, в чем проблема,все предложения и решения будут оценены.

Мой реальный код выглядит примерно так.

class client_session
{ 
   public:
   client_session(boost::asio::io_service& io_service_ )tcp_socekt_(io_service_),
                                                        timer_(io_service_)
   {
   }

   ~client_session()
   {
       tcp_socket_.close();
   }

   void OnTimerExpired(const boost::system::error_code& err)
   {
      if( err ) tcp_socket_.close();
   }

   //Its just for example this will be called from upper layer of my module. giving some information about the server.
   void connect()
   {
        //Here am starting the timer 
        timer_.expires_from_now(boost::posix_time::seconds(2));
        timer_.async_wait(boost::bind(&OutgoingSession::OnTimerExpiry, this,PLACEHLDRS::error));

        .......

        tcp_socket_.async_connect(iterator->endpoint(), boost::bind( &OutgoingSession::handle_connect, this, _1, iterator));

        ......
   }

   void OnConnect(const boost::system::error_code& err)
   {
      //Cancelling the timer 
      timer_.cancel();
      .....
      //Register for write to send the request to server
      ......
   }

   private:
   tcp::socket tcp_socket_;
   deadline_timer timer_;
} 

void main()
{
  boost::asio::io_service tcp_io_service;
  boost::asio::io_service::work tcp_work(tcp_io_service);

  boost::thread* worker = new boost::thread(&boost::asio::io_service::run,&tcp_io_service);

  client_session* csession = new client_session(tcp_io_service);
  csession->connect();

  sleep(10);

  tcp_io_service.stop();

  delete csession;

  worker.join();    //Here it not coming out of join because io_service::run() is not exited yet.
  cout<<"Termination successfull"<<endl;
}

1 Ответ

1 голос
/ 28 декабря 2011

В опубликованном коде, похоже, что-то не так.Я бы посоветовал начать с более мелких шагов, т. Е. Вдоль строк

  • start и stop рабочего потока asio (см. Пояснение ниже)
  • добавить код для запуска таймера: handleOnTimerExpired правильно, проверьте код ошибки
  • добавьте код для async_connect: при вызове обработчика соединения таймер cancel и проверьте код ошибки.
  • добавьте в другие асинхронные операции и т. Д..

Например, если вы cancel отметите таймер в обработчике соединения, обработчик OnTimerExpired будет вызван с boost::asio::operation_aborted, а затем вы close сокет, что, вероятно, нечто вы хотите сделать.

Кроме того, вы даете работу io_service, но все равно звоните stop.Как правило, если вы даете работу io_service, вы хотите остановить поток выполнения, удалив работу (например, это можно сделать путем сохранения работы в интеллектуальном указателе и ее сброса) и позволяя текущим запущенным асинхронным операциям завершаться чисто.

...