每个线程完成后停止io_service

Awa*_*One 0 c++ boost boost-thread boost-asio

我想让程序等待,直到它完成所有正在运行的线程ioService.stop();,这与一样,ioService无需等待即可停止。我尝试了以下代码,该代码工作正常,但ioService无需等待线程完成即可停止。

#include <iostream>
#include <boost/asio/io_service.hpp>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>


void myTask (std::string &str);

int main(int argc, char **argv){

    uint16_t total_threads = 4;

    /*
     * Create an asio::io_service and a thread_group
     */
    boost::asio::io_service ioService;
    boost::thread_group threadpool;    

    /*
     * This will start the ioService processing loop. 
     */     
    boost::asio::io_service::work work(ioService);

    /*
     * This will add threads to the thread pool.
     */
    for (std::size_t i = 0; i < total_threads; ++i)
        threadpool.create_thread(
                boost::bind(&boost::asio::io_service::run, &ioService));    

    /*
     * This will assign tasks to the thread pool.
     */
    std::string str = "Hello world";
    ioService.post(boost::bind(myTask, std::ref(str) ));



    ioService.stop();

    /*
     * thread pool are finished with
     * their assigned tasks and 'join' them.
     */
    threadpool.join_all();

    return 0;

}


void myTask (std::string &str){
    std::cout << str << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

编译: -lboost_serialization -lboost_thread -lboost_system

Haj*_*off 5

您的问题是要work在堆栈上创建为变量。work告诉io_service仍有工作要做。从手册中:

析构函数通知io_service工作已完成。

由于工作是在堆栈的main中创建的,因此它的生存期比您希望的要长。在主出口退出之前,它不会被破坏。而是在堆上创建它,以便您可以显式销毁它。更改为:

using namespace boost::asio;
boost::scoped_ptr<io_service::work> work(new io_service::work(ioService));
Run Code Online (Sandbox Code Playgroud)

然后,稍后,当您要让io_service在完成所有未完成的工作后停止时,请不要停止io_service而是销毁“工作”,然后等待线程完成。

work.reset();
threadpool.join_all();
Run Code Online (Sandbox Code Playgroud)

这将调用~work(),这将从io_service中删除工作对象。这将导致io_service::run最后一个挂起的操作完成后退出。

一些注意事项:

  • 我会避免给变量一个与它的类相同的名称。我不会写io_service::work work(io_service);太混乱了。我会写类似io_service::work some_work(io_service);
  • 请注意,io_service.post(... std::ref(str));您正在传递对io_service post操作的引用。变量str必须生存足够长的时间才能完成任务。我确定这只是示例。在实际应用中,很难确保传递给工作对象的参数不会过早地被破坏。我用shared_ptr<>了很多,或者在不可能的情况下,有时我用boost :: atomic计算未完成的io_service操作的数量