提升 io_service 非阻塞并行执行?

boost io_service non-blocking parallel execution?

我在使用 boost::asio 和 boost::io_service

时遇到了难题

我的 classes 围绕着 boost 为套接字连接提供的 async client example。 我使用另一个 class 封装:

class service_controller
{
    ...

    /// IO service
    boost::asio::io_service __io_service;

    /// Endpoint Resolver
    boost::asio::ip::tcp::resolver::query __query;

    /// Resolution for TCP
    boost::asio::ip::tcp::resolver __resolver;
}

所以,当我构造我的客户时,构造函数采用引用:

asio_service_client (
                        boost::asio::ip::tcp::resolver::query & query,
                        boost::asio::ip::tcp::resolver & resolver,
                        boost::asio::io_service & io_service
                    );

一切正常,但我必须打电话给

io_service.run()

最后,在创建了我所有的客户之后。 如果我为每个客户端封装单独的 io_service 对象,我基本上删除了异步 io 性质,因为每个对象都会阻塞直到完成。 因此,我决定形成一种类型的组,使所有客户端对象都使用相同的 io_service.

io_service::poll() 似乎根本不起作用(没有任何反应),io_service::run_one() 也没有。

事实上,唯一似乎有效的是:

    // with a callback => the callback will run once finished
    rapp::services::asio_service_client c1( ctrl.Query(), ctrl.Resolver(), ctrl.Services() );

    // without a callback => asio_service_client::handle_reply will run once finished
    rapp::services::asio_service_client c2 ( ctrl.Query(), ctrl.Resolver(), ctrl.Services() );
    rapp::services::asio_service_client c3 ( ctrl.Query(), ctrl.Resolver(), ctrl.Services() );
    rapp::services::asio_service_client c4 ( ctrl.Query(), ctrl.Resolver(), ctrl.Services() );

    // Run services c1, c2
    c1.Run( header, post,
            [&]( boost::asio::streambuf & buffer )
            { 
                std::string raw ( ( std::istreambuf_iterator<char>( &buffer ) ), std::istreambuf_iterator<char>() );
                std::cout << raw << std::endl;
            });

    c2.Run( header, post );
    ctrl.Services().run();

    /// Run remaining services ( c3, c4 )
    c3.Run( header, post );
    c4.Run( header, post );

    ctrl.Services().reset();
    ctrl.Services().run();

当然,除非我要求一个组一起运行(例如,要求运行 c1、c2、c3 和 c4)。

是否有某种方式或某种 class 模式,我可以在其中自动创建一个队列,在其中创建对象,添加它们,然后它们异步运行?理想情况下有线程,但没有也可以。

某种堆栈,当我添加对象时,它们会在添加时异步执行。

如果我尝试类似的操作:

Scheduler::Execute ( asio_service_client & client )
{
   client.Run( ... )
   io_service.reset();
   io_service.run();
}

我会重置之前运行的服务,重新开始,这不是我想要的。 我唯一明显的选择是接受并为每个添加的 io_service_client 分配一个单独的 io_service,或者强制将它们一起添加到一个作业组中,然后执行?

我能想到的另一个解决方案是使用线程,因此,每个 asio_service_client 将在自己的线程中运行,因此不会阻塞其他 asio_service_clients,执行并行?

您可能想要共享一个 io_service 实例和 post 上面的一个 io_service::work 对象,这样即使当前没有客户端有任何待处理的异步操作,它也会保持活动状态:

boost::asio::io_service io_service;
auto work = boost::make_shared<boost::asio::io_service::work>(io_service);

// any client can post it's asynchronous operations on this service object, from any thread

// completion handlers will be invoked on any thread that runs `io_service.run()`

// once you want the `io_service` to empty the queue and return:
work.reset();

// now `run()` will return when it runs out of queued tasks