可以提升:asio io_service.run()在循环中不止一次调用?

问题描述:

我正在使用boost::asio来建立一个异步客户端通信类。可以提升:asio io_service.run()在循环中不止一次调用?

在我的设计中,我有一个类(AsioThread)和一个作为独立线程启动的主运行方法。这里是类方法代码:

void AsioThread::Run() 
    { 
     while (true) 
     { 
      transactionMutex.lock(); 

      switch (asioState) 
      { 
       case (AsioStateType::Connect): // Start a connection 
       { 
        std::string address = currentCommand.arguments["address"]; 
        std::string port = currentCommand.arguments["port"]; 

        asioState = AsioStateType::ConnectWait; 

        boost::asio::ip::tcp::resolver::iterator end; 

        if (currentEndPoints == end) 
        { 
         boost::asio::io_service ios; 
         boost::asio::ip::tcp::resolver resolver(ios); 
         boost::asio::ip::tcp::resolver::query query(address, port); 
         currentEndPoints = resolver.resolve(query); 
        } 
        else 
        { 
         currentEndPoints++; 
        } 

        currentSocket->close(); 
        currentSocket->async_connect(*currentEndPoints, boost::bind(&AsioThread::ConnectHandler, this, _1));  
        break; 
       } 

       case (AsioStateType::ConnectResponse): // Receive connection welcome message 
       { 
        asioState = AsioStateType::ConnectResponseWait; 
        currentSocket->async_receive(boost::asio::buffer(boost::asio::buffer(rxBuffer, MAX_BUFFER_SIZE)), 0, boost::bind(&AsioThread::ReceiveDataHandler, this, _1, _2)); 
        break; 
       } 
      } 

      transactionMutex.unlock(); 

      ioService.run(); 
      std::this_thread::sleep_for(std::chrono::milliseconds(100)); 
     } 
    } 

有了这段代码,回调函数永远不会被调用。如果我将ioService.run()放在async_connect或async_receive行之后,则会调用它来进行连接 - 而不是接收消息。另外,如果我添加调试线,如:

`std::cout << "I´m here " << std::endl´ 

有时回调是所谓的,这取决于我把这个调试代码的地方。

对我来说,我错了,使用ioService.run()。请注意,每次循环传递都会调用它(每秒10次)。

互斥量用于控制其他线程对asioState的写入访问 - 其他线程通过使用此成员变量传递的消息来命令此主循环操作。

帮助表示赞赏找到出路what's错在这里...

+0

这不是使用asio的方式。阅读文档中的示例。 http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/example/cpp03/http/client/async_client.cpp –

+0

你的意思是只有一种方法可以使用asio? – Mendes

+0

不,有几种方法,但是从线程或线程池中为io服务提供服务是使用它的特定方式,并且存在正确的习惯用法。您需要创建一个工作对象以防止io服务停止。当您希望工作线程停止时,请在io服务上调用stop()。 –

io_service::run()用完的工作,它返回。在异步操作之后调用ioService.run()时发生的情况是,它允许该操作完成,然后耗尽工作并返回。排队下一个操作后,您需要运行到io_service以处理操作。

另一种方法是在提交boost::io_service::work对象以保持活动状态后,让线程运行ioService::run()。要处理switch语句中的情况,您可以使用io_service::post()触发操作,以便在运行处理程序内运行它们而不是轮询状态变量。当你想关闭线程时,销毁工作对象。

+0

我没有得到你说的那句话:“在将下一个操作排队后,你需要运行io_service来处理操作。”我在每次交互时调用ioService.run()... – Mendes

+0

如果io_service耗尽工作,它将处于“stopped()”状态。你需要“重置()”来让它在你完成一些工作后再做更多的工作。 –