考虑以下示例类,该类允许一个线程等待来自另一个线程的信号。

class Sync
{
    std::mutex mtx, access;
    std::condition_variable cv;
    bool waiting;

public:
    Sync()
        : waiting(false)
    {
    }
    Sync(const Sync&);
    ~Sync()
    {
        sendSignal();
    }

    void waitForSignal()
    {
        access.lock();
        if (!waiting)
        {
            std::unique_lock<std::mutex> lck (mtx);
            waiting = true;
            access.unlock();

            // in the time between these two statements, 'sendSignal()' acquires
            // the lock and calls 'cv.notify_all()', thus the signal was missed.

            cv.wait(lck);
        }
        else
            access.unlock();
    }
    void sendSignal()
    {
        access.lock();
        if (waiting)
        {
            std::unique_lock<std::mutex> lck (mtx);
            cv.notify_all();
            waiting = false;
        }
        access.unlock();
    }
};


我遇到的问题是,在解锁“互斥”互斥锁和在condition_variable上调用“ wait()”之间的时间间隔内,由于交织有时会丢失信号。我该如何预防?

最佳答案

您可能应该只有一个互斥锁。我不明白您为什么需要访问权限。使用mtx保护等待变量和条件变量。

类同步
{
    std :: mutex mtx;
    std :: condition_variable cv;
    布尔等待;

上市:
    同步()
        :等待中(false)
    {
    }
    同步(const Sync&);
    〜Sync()
    {
        sendSignal();
    }

    void waitForSignal()
    {
        std :: unique_lock lck(mtx);
        如果(正在等待)
        {
            等待=真;

            cv.wait(lck);
        }
    }
    无效sendSignal()
    {
        std :: unique_lock lck(mtx);
        如果(等待)
        {
            cv.notify_all();
            等待=假;
        }
    }
};


等待变量和条件变量状态联系在一起,因此应将它们视为单个关键部分。

09-11 19:43