我们有一个多线程应用程序。在当前实现中, thread1 在启动时创建,并定期(每隔一秒左右,可配置)唤醒以检查磁盘是否存在潜在的已保存文件。这些文件由另一个线程 thread2 保存。运行 thread1 并定期唤醒可能会降低应用程序的速度。
现在我们有机会使用boost :: condition变量来阻止 thread1 ,直到 thread2 通知它。通过这样做,需要创建一个标志以避免来自 thread2 的不必要的通知,并且该标志需要被同步并且通过 thread2 。或者每次写入时都会通知 thread1 。
我的问题如下:
在boost :: condition实现中, thread1 仍然需要经常唤醒以检查标志,不同之处在于实现对我们是隐藏的,但它实际上是这样做的。我对吗? Windows和Java中的类似API也做同样的事情吗?
如果线程经常被多次通知,即使它没有处于等待状态,会发生什么?
在我的情况下,它会通过切换到boost :: condition实现来提高整体性能吗?我的意见是否。
答案 0 :(得分:1)
这个想法是,如果不等待条件,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