与阻止呼叫同步

Synchronization with blocking call

本文关键字:同步 呼叫      更新时间:2023-10-16

假设我有一个具有以下接口的类:

class IEvent
{
    void SetEvent() = 0;
    void WaitForEvent() = 0;
}

WaitForEvent()是一个阻止功能,等待直到另一个线程调用SetEvent()函数。

我正在为此课程编写单元测试,并且需要以下方案:

第一个线程调用WaitForEvent()。之后第二个线程致电SetEvent()

如何同步SetEvent()调用将始终遵循WaitForEvent()调用的线程?

我不想使用任何睡眠,因为我希望单位测试尽可能快地进行。

这是我可以管理的最好的

#include <mutex>
#include <condition_variable>
#include <thread>
#include <iostream>
class IEvent
{
public:
    virtual void SetEvent() = 0;
    virtual void WaitForEvent() = 0;
};
class EventClass : public IEvent
{
public:
    void SetEvent() override {
        std::unique_lock<std::mutex> lock { _mutex };
        std::cout << "setting eventn";
        _event = true;
        lock.unlock();
        _cv.notify_all();
    }
    void WaitForEvent() override {
        std::unique_lock<std::mutex> lock { _mutex };
        std::cout << "waiting for eventn";
        _cv.wait(lock, [this]{ return _event; });
        std::cout << "waiting completen";
    };
private:
    std::mutex _mutex;
    std::condition_variable _cv;
    bool _event = false;
};
int main()
{
    EventClass object;
    std::mutex cv_mutex;
    std::condition_variable may_set_cv;
    bool may_set_event = false;
    auto setting_thread = std::thread([&]{
        std::unique_lock<std::mutex> lock { cv_mutex };
        may_set_cv.wait(lock,
                        [&] {
                            return may_set_event;
                        });
        object.SetEvent();
    });
    std::unique_lock<std::mutex> lock { cv_mutex };
    may_set_event = true;
    lock.unlock();
    may_set_cv.notify_one();
    // tiny race condition here
    object.WaitForEvent();
    setting_thread.join();
}