【问题标题】:Will boost::condition improve the performance?boost::condition 会提高性能吗?
【发布时间】:2013-10-02 15:41:00
【问题描述】:

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

现在我们有机会使用 boost::condition 变量将 thread1 阻塞,直到 thread2 通知它。通过这样做,需要创建一个标志以避免来自 thread2 的不必要通知,并且该标志需要同步并由 thread2以高频率(几秒钟内数百次)检查>。或者 thread1 在每次写入时都会收到通知。

我的问题如下:

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

  2. 如果一个线程不处于等待状态,但频繁多次通知会发生什么?

  3. 在我的例子中,它会通过切换到 boost::condition 实现来提高整体性能?我的意见是不。

【问题讨论】:

  • 这取决于 boost::condition 是如何实现的。如果它使用系统条件变量,则线程 1 应退出调度,直到收到通知,在收到通知之前不会唤醒。
  • 您提到的标志是在创建新文件时设置并在线程1完成此文件时重置?
  • 是的。 thread2 设置该标志以让 thread1 知道文件已准备好。 thread1 将处理它,然后重置该标志。

标签: c++ multithreading boost boost-thread


【解决方案1】:
  1. 在 POSIX 和 Win32 中 boost::condition 是使用基于事件的 API 实现的。从技术上讲,线程在收到事件之前不会唤醒。
  2. 如果在发送信号后线程进入等待 - 信号将丢失。您应该阅读有关实现“生产者/消费者”的基于事件的模式和策略。您的文件写入/读取示例是经典的生产者/消费者实例。为了避免丢失信号,请按照 Wikipedia 中的 C++11 示例来实现它:http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem#Example_in_C.2B.2B

这个想法是,如果 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。性能问题:此更改与性能无关,而是将轮询更改为事件模型。如果您的线程 1 每 1 秒唤醒一次,则切换到事件模型不会改善 CPU 或 I/O 负载(消除每 1 秒一次的文件验证),直到您在频率为几 KHz 且 I/O 操作阻塞的嵌入式系统中运行整个过程。 它将提高线程 1 的反应时间,在轮询模式下,文件更改的最大响应时间为 1 秒,切换到事件后将立即采取行动。 另一方面,线程 2 的性能可能会在事件模型中下降——在它没有等待任何东西之前,并且如果它使用条件——它必须锁定共享互斥体,这可能在线程 1 读取文件时一直被锁定。

【讨论】:

    【解决方案2】:

    高频率检查标志正是 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

    【讨论】:

      猜你喜欢
      • 2013-04-12
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-13
      • 2010-10-23
      • 2012-12-14
      相关资源
      最近更新 更多