Будет ли добавление пустой области блокировки перед уведомлением переменной условия предотвратить потерянные уведомления? - PullRequest
0 голосов
/ 09 июля 2019

Рассмотрим предикат, который проверяет наличие обновленных флагов вне блокировки мьютекса переменной условия (поскольку я хочу абстрагироваться от реализации ожидания).Будет ли добавление пустой области блокировки перед уведомлением переменной условия предотвратить потерянные уведомления?Вот минимальный пример.

#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();
}
...