13

我尝试在 C++ 中开发一个线程池,我想知道在工作线程的主循环中使用 yield() 线程还是等待条件变量更好:

void worker_thread( void )
{
    // this is more or less pseudocode
    while( !done )
    {

        if( task_available ) 
             run_task();
        else
            std::this_thread::yield();
    }
}

相对

void worker_thread( void )
{
    // this is more or less pseudocode

    std::unique_lock< std::mutex > lk( mutex_ );
    while( !done )
    {

        if( task_available ) 
             run_task();
        else
            condition_.wait( lk );
    }
}

有任何想法吗?两个版本之间会有性能差异吗?

4

2 回答 2

10

如果您在线程池中的线程不断地收到任务并且您需要快速响应时间,那么 yield 就是您想要的,但是无论等待线程在做什么, yield 都会消耗 cpu 周期。如果没有,您可以使用条件方法,线程将休眠直到任务准备好(注意,条件可以唤醒线程,即使没有发送就绪信号),响应时间可能会更慢,但您不会烧毁cpu 周期。

我会推荐有条件的方法,如果反应时间太慢,切换到产量。

于 2013-07-12T11:29:52.087 回答
7

无论哪种方式,线程切换的成本都是相同的。至于是否应该使用轮询或条件变量,后者可以通过关闭线程来让处理器休息,直到真的有事情要做。这导致较低的 CPU 利用率。轮询方法将允许线程返回并“重试”,有效地无限期地运行 CPU。

值得指出的是,有一些应用程序更喜欢轮询,例如在task_available很短的时间内何时为假(即通常有工作要做)。在这种情况下,您将需要task_available使用计数器循环轮询;仅当计数器超过阈值时才产生线程。

于 2013-07-12T11:30:12.440 回答