如何检查io_service中的任务是否完成?

时间:2019-05-29 02:14:16

标签: c++ boost concurrency boost-asio asio

我对users[0].contactDetails.phone有疑问。

我有一组可以同时运行的任务。运行完所有这些之后,我需要同时运行另一组任务。但是,在开始运行第二组之前,必须先完成第一组。这意味着在开始计划第二套作业之前,我需要确保提交给io_service的所有作业都已完成。

我可以通过保留某种计数器并添加一个繁忙的循环来实现它,但是它看起来不是很有效。因此,我想检查某人是否有更好的主意。以下是我用来进行实验的伪代码。

提前谢谢!

boost::io_service

2 个答案:

答案 0 :(得分:1)

您的主要问题是,所有任务集都由io_service的同一实例处理。函数io_service::run返回没有要处理的任务的地方。 io_service::work的析构函数通知io_service对象run可以返回队列中没有待执行任务的地方。您可以发布第一个集合中的所有任务,然后销毁工作,等到io_service::run返回,然后再次创建work对象,发布下一个集合中的任务并删除工作,依此类推。为此,只需编写如下所示的帮助器类:

class TasksWaiter 
{
public:
    TasksWaiter(int numOfThreads) 
    {
        work = std::make_unique<boost::asio::io_service::work>(io_service);
        for(size_t i = 0; i < numOfThreads; ++i) {
            workers.create_thread(boost::bind(&boost::asio::io_service::run, &io_service));
        }
    }

    ~TasksWaiter() {
        work.reset();
        workers.join_all();
    }

    template<class F>
    void post(F f) {
        io_service.post(f);
    }

    boost::thread_group workers;
    boost::asio::io_service io_service;
    std::unique_ptr<boost::asio::io_service::work> work;
};

int main()
{
    {
        TasksWaiter w1{4};
        for (int i = 0; i < numTasks; ++i)
            w1.post(boost::bind(print_counter,i));
        // work in w1 is destroyed, then io_service::run ends 
        // when there are no tasks to be performed
    }
    printf("wait here");
    {
        TasksWaiter w1{4};
        for (int i = 0; i < numTasks; ++i)
            w1.post(boost::bind(print_counter,i));
    }
}

一些评论:

  1. 在线程的构造函数池中创建

  2. 销毁工作中的
  3. 被删除,因此io_service::run仅在没有待处理任务时返回

  4. 析构函数的
  5. 功能可以包装为成员函数-例如wait,那么您不必使用{}范围来等待任务。

答案 1 :(得分:0)

来自the io_service::run documentation

  

run()函数阻塞,直到所有工作完成,并且不再分配处理程序为止,或者直到io_context被停止为止。

另外,来自the io_context::work constructor documentation

  

构造函数用于通知io_context一些工作已经开始。这样可以确保io_context对象的run()函数在正在进行的工作中不会退出

[重点突出]

简而言之,如果run函数返回并且stopped返回false,则所有工作已经完成。