在C ++中使用Boost的线程池无法正常工作

时间:2014-02-07 18:17:51

标签: c++ multithreading boost

我已经实现了How to create a thread pool using boost in C++?的解决方案,但是我遇到了io_service :: stop()函数的问题,阻止了我的线程的进一步处理。

在我的情况下,我的池中有3个线程,我试图通过它运行大约11000条记录。每个记录都独立于其他记录,所以我只是想通过创建每条记录的并行运行来加快处理速度。

void processRecord (unsigned int i, unsigned int numRecords)
{
    cout << i << "/" << numRecords << endl;

    // do Processing...
}

#define MAX_THREADS 3
unsigned int numRecords=11000

boost::asio::io_service ioService;
boost::thread_group threadPool;

boost::asio::io_service::work work (ioService);

for (unsigned int i=0 ; i<MAX_THREADS ; ++i)
{
    threadPool.create_thread (boost::bind (&boost::asio::io_service::run, &ioService));
}

for (unsigned int i=0 ; i<numRecords ; ++i)
{
    ioService.post (boost::bind (processRecord, i, numRecords);
}

// ioService.stop ();          // Was causing ioService to stop
work.reset();                  // Wait for all work to be finished.
threadPool.join_all ();

processAllRecords ();

我看到的问题是,在调用ioService.post()的进程完成后将进程推入池中的循环结束后,它会触发ioService.stop()调用并停止所有进一步处理。这通常发生在实际上只处理了大约400条记录之后。

因此,正在处理~11000条记录中只有约400条记录。

我是C ++中使用线程的新手,所以我不确定我缺少什么或者如何解决这个问题。任何帮助将不胜感激。

编辑:我修改了上面的代码,以反映我为使其工作所做的更改。本质上,ioService.stop()调用导致所有进一步处理停止。我用work.wait()替换它,以便等到所有工作完成。

Edit2:我在之前的编辑中使用了错误的功能。它应该是work.reset()。

1 个答案:

答案 0 :(得分:0)

使用你的代码,我对线程组使用boost :: asio的方式, 将工作括在括号中并使用scoped_ptr。只是一个想法。

void processRecord (unsigned int i, unsigned int numRecords)
{
    cout << i << "/" << numRecords << endl;

    // do Processing...
}

#define MAX_THREADS 3
unsigned int numRecords=11000

boost::asio::io_service ioService;
boost::thread_group threadPool;

// by using a scoped pointer for the io_service::work
// and enclosing the threading in brackets
// this should run until all the jobs have finished
// and you don't need to call work.reset()  

// added brackets around threading
{
    // made work a boost::scoped_ptr
    boost::scoped_ptr< boost::asio::io_service::work > 
          work ( new boost::asio::io_service(ioService) );

    for (unsigned int i=0 ; i<MAX_THREADS ; ++i)
    {
        threadPool.create_thread (
           boost::bind (&boost::asio::io_service::run, &ioService));
    }

    for (unsigned int i=0 ; i<numRecords ; ++i)
    {
        ioService.post (boost::bind (processRecord, i, numRecords);
    }
}
// now just have to join
threadPool.join_all ();

processAllRecords ();