提升asio行为 - 从多个线程调用ios_service :: run

时间:2014-07-20 00:03:05

标签: c++ multithreading boost boost-asio

我正在尝试将boost :: asio截止时间计时器用于延迟函数调用,如下所示

#include <boost/asio.hpp>
#include "boost/thread.hpp"
#include <iostream>

class MyTest {
public:
    MyTest()
    :_invokeCount(0),
     _handleCount(0)
    {}

    void handler(int i)
    {
        std::cout<<"\t\tHandled " <<i << std::endl;
        ++_handleCount;
    }
    void RunIOService()
    {
        std::cout<<"\tStarted :"<< _invokeCount<< std::endl;
        _ios.run();
        std::cout<<"\tFinished "<< _invokeCount << std::endl;
    }
    void invokeTimer()
    {
        std::cout<<"invoked " << ++_invokeCount << std::endl;

        boost::asio::deadline_timer t(_ios, boost::posix_time::milliseconds(5));
        t.async_wait(boost::bind(&MyTest::handler, this, _invokeCount));
        boost::thread th = boost::thread(boost::bind(&MyTest::RunIOService, this));
    }
    void PrintCount()
    {
        std::cout<<"Count = "<< _invokeCount << std::endl;
    }
    void Wait()
    {
        while (_invokeCount > _handleCount) {
            std::cout<<"X ";
            Sleep(1000);
        }
    }

private:
    int _invokeCount;
    int _handleCount;
    boost::asio::io_service _ios;
};

int main(int argc, char* argv[])
{
    MyTest test;
    for (int k=0; k<5; ++k) {
        test.invokeTimer();
        Sleep(40);
    }
    test.Wait();
    test.PrintCount();

    return EXIT_SUCCESS;
}

此应用程序的输出不符合我的预期: -

invoked 1
    Started :1
        Handled 1
    Finished 1
invoked 2
    Started :2
    Finished 2
invoked 3
    Started :3
        Handled 2
    Finished 3
invoked 4
    Started :4
        Handled 3
    Finished 4
invoked 5
    Started :5
        Handled 4
    Finished 5
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

我希望在ios_service :: run返回之前调用每个处理程序,并且它从输出中看起来不是这样(在Started:2和Finished:2之间缺少输出)。此外,该应用程序永远不会退出。即第五个处理程序永远不会被调用。

我错过了什么?

谢谢!

3 个答案:

答案 0 :(得分:2)

有几件事:

  1. 您可能不需要5个主题。为什么不创建单个线程并将事件激活到线程
  2. 中运行的单个ioservice实例中
  3. 尝试在线程运行功能中使用io_service::work,以便在处理完所有请求时将io_service保留在范围内。
  4. 当您的等待完成后,请停止io_service,加入您的主题并让您的程序退出
  5. 请在此处阅读io_service::workhttp://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/io_service.html

答案 1 :(得分:1)

我在每个ios_service :: run()之后添加了ios_service :: reset(),它按预期工作。

答案 2 :(得分:0)

应该在run()的后续调用集之前调用

boost :: asio :: ioservice :: reset()。 正如助推文件所说:  当由于io_service被停止或用完而导致先前调用这些函数时,必须在run(),run_one(),poll()或poll_one()函数的任何第二次或更高版本的调用之前调用此函数。工作。此功能允许io_service重置任何内部状态,例如&#34;已停止&#34;标志。

当对run(),run_one(),poll()或poll_one()函数进行任何未完成的调用时,不得调用此函数。