Повысить эквивалент ManualResetEvent? - PullRequest
12 голосов
/ 01 октября 2009

Мне интересно, есть ли буст-эквивалент ManualResetEvent? По сути, я бы хотел кроссплатформенную реализацию ... Или кто-нибудь может мне помочь имитировать функционал ManualResetEvent, используя Boost :: thread? Спасибо, ребята

Ответы [ 2 ]

12 голосов
/ 01 октября 2009

Довольно просто написать событие ручного сброса, если у вас есть мьютексы и условные переменные.

Вам понадобится поле, представляющее, сигнализировано ли событие сброса или нет. Доступ к полю должен быть защищен мьютексом - это включает в себя как настройку / сброс вашего события, так и проверку, если оно сигнализируется.

Когда вы ожидаете своего события, если оно в настоящий момент не передано, вы захотите подождать переменную условия, пока оно не будет передано. Наконец, в вашем коде, который устанавливает событие, вы захотите уведомить переменную условия, чтобы разбудить любого, кто ожидает вашего события.

class manual_reset_event
{
public:
    manual_reset_event(bool signaled = false)
        : signaled_(signaled)
    {
    }

    void set()
    {
        {
            boost::lock_guard<boost::mutex> lock(m_);
            signaled_ = true;
        }

        // Notify all because until the event is manually
        // reset, all waiters should be able to see event signalling
        cv_.notify_all();
    }

    void unset()
    {
        boost::lock_guard<boost::mutex> lock(m_);
        signaled_ = false;
    }


    void wait()
    {
        boost::lock_guard<boost::mutex> lock(m_);
        while (!signaled_)
        {
            cv_.wait(lock);
        }
    }

private:
    boost::mutex m_;
    boost::condition_variable cv_;
    bool signaled_;
};
1 голос
/ 01 октября 2009

IIRC, ManualResetEvent существуют для того, чтобы несколько потоков могли ожидать объекта, и один поток просыпался в момент, когда объект сигнализируется. Часть «ручной сброс» происходит из-за того, что система не сбрасывает событие автоматически после пробуждения потока; Вы делаете это вместо этого.

Это звучит очень похоже на переменные условия :

Общая схема использования заключается в том, что один поток блокирует мьютекс, а затем вызывает wait в экземпляре condition_variable или condition_variable_any. Когда поток просыпается от ожидания, он проверяет, является ли соответствующее условие истинным, и продолжает, если это так. Если условие не истинно, тогда поток снова вызывает wait, чтобы возобновить ожидание.

...