【问题标题】:boost::thread_group - is it ok to call create_thread after join_all?boost::thread_group - 可以在 join_all 之后调用 create_thread 吗?
【发布时间】:2010-02-18 16:39:20
【问题描述】:

我有以下情况:

我创建了一个 boost::thread_group 实例,然后为一些数据创建并行处理线程,然后在线程上加入 join_all。

最初我为每个 X 数据元素创建线程,如下所示:

// begin = someVector.begin();
// end = someVector.end();
// batchDispatcher = boost::function<void(It, It)>(...);

boost::thread_group     processors;

// create dispatching thread every ASYNCH_PROCESSING_THRESHOLD notifications
while(end - begin > ASYNCH_PROCESSING_THRESHOLD)
{
    NotifItr split = begin + ASYNCH_PROCESSING_THRESHOLD;

    processors.create_thread(boost::bind(batchDispatcher, begin, split));
    begin = split;
}

// create dispatching thread for the remainder
if(begin < end)
{
    processors.create_thread(boost::bind(batchDispatcher, begin, end));
}

// wait for parallel processing to finish
processors.join_all();

但我有一个问题:当我有大量数据时,这段代码会生成大量线程(> 40 个线程),这会使处理器忙于线程切换上下文。

我的问题是:在调用 join_all 之后 是否可以在 thread_group 上调用 create_thread。

也就是说,我可以把我的代码改成这样吗?

boost::thread_group     processors;
size_t                  processorThreads = 0; // NEW CODE

// create dispatching thread every ASYNCH_PROCESSING_THRESHOLD notifications
while(end - begin > ASYNCH_PROCESSING_THRESHOLD)
{
    NotifItr split = begin + ASYNCH_PROCESSING_THRESHOLD;

    processors.create_thread(boost::bind(batchDispatcher, begin, split));
    begin = split;

    if(++processorThreads >= MAX_ASYNCH_PROCESSORS) // NEW CODE
    {                               // NEW CODE
        processors.join_all();      // NEW CODE
        processorThreads = 0;       // NEW CODE
    }                               // NEW CODE
}

// ... 

谁有这方面的经验,感谢任何见解。

【问题讨论】:

    标签: c++ parallel-processing boost-thread


    【解决方案1】:

    我相信这是不可能的。您想要的解决方案实际上可能是实现producer-consumer 或主工作者(主“主”线程将工作划分为几个固定大小的任务,创建“工作者”线程池并将一个任务发送给每个工作者,直到所有任务完成)。

    这些解决方案需要通过信号量进行一些同步,但它们会很好地平衡性能,您可以为机器中的每个可用内核创建一个线程,避免在上下文切换上浪费时间。

    另一个不太好的选择是一次加入一个线程。您可以拥有一个具有 4 个活动线程的向量,加入一个并创建另一个。这种方法的问题是,如果您的任务是异构的,您可能会浪费处理时间。

    【讨论】:

    • 代码按原样运行(就像我提出的解决方案一样),但我不确定它是否稳定。我已经实现了一个在 join_all 之后显式删除死线程的版本。这不是最有效的实现方式,但现在可以使用(此处建议:groups.google.com/group/boost-list/browse_thread/thread/…)我还将研究实现生产者-消费者解决方案(谢谢)。
    猜你喜欢
    • 1970-01-01
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 2012-04-11
    • 2013-10-01
    • 2011-12-15
    相关资源
    最近更新 更多