条件变量中错误信号的触发频率是多少?
How often false signals are triggered in a condition variable?
我不明白为什么 std::condition_variable 比这段代码有更多的标准保证:
class condition_variable {
public:
void notify_one() {}
void notify_all() {}
void wait(unique_lock<mutex> &lock) {
lock.unlock();
this_thread::sleep_for(15ms);
lock.lock();
}
void wait(unique_lock<mutex> &lock,
const function<bool()> &pred) {
while (!pred()) wait(lock);
}
};
std::condition_variable::wait()
的最简单实现只对应于 busy waiting:
template<typename Predicate>
void wait(std::unique_lock<std::mutex>& lck, Predicate pred) {
while (!pred()) {
lck.unlock();
lck.lock();
}
}
因此,可能会发生 虚假唤醒。
您的实现使线程在释放和获取互斥锁之间进入休眠状态:
void wait(unique_lock<mutex> &lock) {
lock.unlock();
this_thread::sleep_for(15ms); // <--
lock.lock();
}
不过,找到合适的睡眠时间可能很困难。它越低,越像忙等待,因此浪费的 CPU 个周期越多。它越高,浪费的 CPU 周期越少,但响应能力越差。
在您的实现中发生虚假唤醒的频率取决于休眠期的选择。
条件变量旨在使用a semaphore,它允许在不使用CPU 循环的情况下等待。您的实现反复锁定和解锁互斥锁,如果没有睡眠,它将消耗 100% 的 CPU.
有了sleep,唤醒时有一个固定的延迟,这与信号量相比也是一个劣势。操作系统知道谁在等待每个条件变量,因此唤醒效率很高。
在Windows上,std::condition_variable
会使用SleepConditionVariableCS等待,一般利用操作系统条件变量API。
我不明白为什么 std::condition_variable 比这段代码有更多的标准保证:
class condition_variable {
public:
void notify_one() {}
void notify_all() {}
void wait(unique_lock<mutex> &lock) {
lock.unlock();
this_thread::sleep_for(15ms);
lock.lock();
}
void wait(unique_lock<mutex> &lock,
const function<bool()> &pred) {
while (!pred()) wait(lock);
}
};
std::condition_variable::wait()
的最简单实现只对应于 busy waiting:
template<typename Predicate>
void wait(std::unique_lock<std::mutex>& lck, Predicate pred) {
while (!pred()) {
lck.unlock();
lck.lock();
}
}
因此,可能会发生 虚假唤醒。
您的实现使线程在释放和获取互斥锁之间进入休眠状态:
void wait(unique_lock<mutex> &lock) {
lock.unlock();
this_thread::sleep_for(15ms); // <--
lock.lock();
}
不过,找到合适的睡眠时间可能很困难。它越低,越像忙等待,因此浪费的 CPU 个周期越多。它越高,浪费的 CPU 周期越少,但响应能力越差。
在您的实现中发生虚假唤醒的频率取决于休眠期的选择。
条件变量旨在使用a semaphore,它允许在不使用CPU 循环的情况下等待。您的实现反复锁定和解锁互斥锁,如果没有睡眠,它将消耗 100% 的 CPU.
有了sleep,唤醒时有一个固定的延迟,这与信号量相比也是一个劣势。操作系统知道谁在等待每个条件变量,因此唤醒效率很高。
在Windows上,std::condition_variable
会使用SleepConditionVariableCS等待,一般利用操作系统条件变量API。