boost :: condition会改善性能吗?

时间:2013-10-02 15:41:01

标签: c++ multithreading boost boost-thread

我们有一个多线程应用程序。在当前实现中, thread1 在启动时创建,并定期(每隔一秒左右,可配置)唤醒以检查磁盘是否存在潜在的已保存文件。这些文件由另一个线程 thread2 保存。运行 thread1 并定期唤醒可能会降低应用程序的速度。

现在我们有机会使用boost :: condition变量来阻止 thread1 ,直到 thread2 通知它。通过这样做,需要创建一个标志以避免来自 thread2 的不必要的通知,并且该标志需要被同步并且通过 thread2 。或者每次写入时都会通知 thread1

我的问题如下:

  1. 在boost :: condition实现中, thread1 仍然需要经常唤醒以检查标志,不同之处在于实现对我们是隐藏的,但它实际上是这样做的。我对吗? Windows和Java中的类似API也做同样的事情吗?

  2. 如果线程经常被多次通知,即使它没有处于等待状态,会发生什么?

  3. 在我的情况下,它会通过切换到boost :: condition实现来提高整体性能吗?我的意见是否。

2 个答案:

答案 0 :(得分:1)

  1. 在POSIX和Win32中,boost :: condition是使用基于事件的API实现的。从技术上讲,线程在发生事件之前不会被唤醒。
  2. 如果线程在信号发送后进入等待状态 - 信号将丢失。您应该阅读有关实现“生产者/消费者”的基于事件的模式和策略。您的文件写/读示例是经典的生产者/消费者实例。为了避免信号丢失,请按照维基百科中的C ++ 11示例实现它:http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem#Example_in_C.2B.2B
  3. 这个想法是,如果不等待条件,thread1将始终锁定共享互斥锁:

    //thread1 - consumer
    void thread1() {
        boost::scoped_lock lock(sharedMutex);
        // shared mutex locked, no events can be sent now
        while(1) {
            // check for files written by thread2
            sharedCond.wait( lock ); // this action unlocks the shared mutex, events can be sent now
        }
    }
    
    //thread2 - producer
    void thread2() {
        boost::scoped_lock lock(sharedMutex); // will wait here until thread 1 starts waiting
        // write files
        sharedCond.notify_one();
    }
    

    3。性能问题:此更改与性能无关,而是将轮询更改为事件模型。如果你的thread1每1秒唤醒一次,切换到事件模型将不会改善CPU或I / O负载(每1秒消除文件验证),直到你在频率为几KHz的嵌入式系统中运行并且I / O操作阻止整个过程。 它将改善thread1的反应时间,在轮询模式下,文件更改的最大响应时间为1秒,切换到事件后,它将立即执行。 另一方面,thread2性能可能会在事件模型中降级 - 在它没有等待任何事情之前,如果它使用条件 - 它将必须锁定共享互斥锁,这可能在thread1正在读取文件时被锁定。

答案 1 :(得分:0)

检查高频标志正是boost :: condition允许你避免的。 thread1()只等待flag设置:

#include <mutex>
#include <condition_variable>
#include <thread>

std::mutex mut;
bool flag;
std::condition_variable data_cond;

void thread2()
{
    //here, writing to a file
    std::lock_guard<std::mutex> lk(mut);
    flag = true;  //a new file is saved
    data_cond.notify_one();
}

void thread1()
{
    while(true)
    {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk,[]{return flag;});
        //here, processing the file
        flag = false;
        lk.unlock();
    }
}

这是基于清单4_1的C ++ 11代码:C++ Concurrency in Action, Chapter 4 Synchronizing concurrent operations