Рассмотрим предикат, который проверяет наличие обновленных флагов вне блокировки мьютекса переменной условия (поскольку я хочу абстрагироваться от реализации ожидания).Будет ли добавление пустой области блокировки перед уведомлением переменной условия предотвратить потерянные уведомления?Вот минимальный пример.
#include <condition_variable>
#include <mutex>
#include <atomic>
#include <functional>
#include <thread>
class TaskScheduler {
public:
static void someMethod(std::function<bool(void)>&& pred) {
_wait(std::move(pred));
}
static void notify() {
{
std::lock_guard<std::mutex> lock(waitMutex);
}
waitCV.notify_all();
}
private:
static std::mutex waitMutex;
static std::condition_variable waitCV;
static void _wait(std::function<bool(void)>&& pred) {
std::unique_lock<std::mutex> lock(waitMutex);
waitCV.wait(lock, [&](){return pred();});
}
};
std::mutex TaskScheduler::waitMutex;
std::condition_variable TaskScheduler::waitCV;
std::atomic<bool> waiting{false};
std::atomic<bool> atomicFlag{false};
void thread1() {
TaskScheduler::someMethod([&](){waiting = true; return atomicFlag.load();});
}
void thread2() {
// this is called while thread1 is waiting
atomicFlag = true;
TaskScheduler::notify();
}
int main(int argc, char **argv) {
std::thread th1([&](){thread1();});
while (!waiting) {};
std::thread th2([&](){thread2();});
th2.join();
th1.join();
}