将thread_pool与deadline_timer结合使用 - 模板问题(时间)

时间:2017-04-19 16:28:07

标签: c++ boost-asio

我已经集成了Boost的asio服务,并将其与线程池结合使用。

创建了一个处理期货和异步任务的线程池,我想进一步扩展它以处理截止时间定时器(反模式?)。不幸的是,我在理解处理模板化代码方面达到了极限。更确切地说,我想传递一个boost :: posix_time(例如:boost :: posix_time :: milliseconds(100)或boost :: posix_time :: seconds(5)),但我很难理解我的能力使这成为可能。

以下代码的部分列表是我的线程池的当前实现。

//////////////////////////////////////////////////////////////////////////
class thread_pool
{
public:

    // ...
    // Other boring stuff here...


    //////////////////////////////////////////////////////////////////////////
    template<class Task>
    void enqueue_async(Task task)
    {
        m_pIO->post( std::bind(&thread_pool::wrap_task, this,
                                                  std::function< void() >( task )));
    }

    //////////////////////////////////////////////////////////////////////////
    // NOTE: Needing help here - 'expiry_time' should be relative.
    template <class Task, class ???>
    void enqueue_deadline_async(Task task, const ??? & expiry_time)
    {
        const std::shared_ptr<boost::asio::basic_deadline_timer<???> > apTimer = std::make_shared<boost::asio::deadline_timer>(*get_service_pointer(), expiry_time);
        apTimer->async_wait(std::bind(&thread_pool::enqueue_async, this, task));
    }

private:

    //////////////////////////////////////////////////////////////////////////
    void wrap_task( std::function< void() > task )
    {
        try
        {
            task();
        }
        catch (const std::exception &e)
        {
            // Todo: Log that there is a problem!!
            BOOST_ASSERT_MSG(0,e.what());
        }
    }

};

到目前为止,我一直在使用enqueue_task(...)来排队异步任务以供线程池处理。我现在想扩展线程池,以便能够异步调用一个回调参数到截止时间计时器(参见enqueue_deadline_async())但是让线程池处理任务。

将thread_pool与deadline_time集成的原因是:

  • 最小化代码中并发运行的io_services的数量。
  • 防止deadline_time过长地阻止io_service - 减少对其他待处理计时器的影响。

最后,我在io_service中的嵌套调用是危险的吗?

环境配置:

  • Ubuntu v17.04(Zesty)x86_x64
  • Boost v1.63
  • GCC 6.3

1 个答案:

答案 0 :(得分:2)

一些事情,

template <class Task, class ???>
void enqueue_deadline_async(Task task, const ??? & expiry_time)

因为它是一个可推导的模板参数,只需将其命名为“你已完成”

template <class Task, class T>
void enqueue_deadline_async(Task task, const T & expiry_time)

接下来:

const std::shared_ptr<boost::asio::basic_deadline_timer<???> > apTimer = std::make_shared<boost::asio::deadline_timer>(*get_service_pointer(), expiry_time);

首先,boost::asio::deadline_timer已经允许您在问题中提供所需内容。所以不要与basic_deadline_timer混淆。其次,共享指针无论如何都需要转换为apTimer类型,这使得它更没用(因为选择另一个计时时钟模型甚至无法编译)。

解决方案

只需使用deadline_timer也使用的界面:

template <class Task>
void enqueue_deadline_async(Task task, const boost::posix_time::time_duration& expiry_time)

有效:

int main() {
    thread_pool tp;
    tp.enqueue_deadline_async([]{ }, boost::posix_time::seconds(5));
    tp.enqueue_deadline_async([]{ }, boost::posix_time::milliseconds(5));
}
相关问题