Повышение, эквивалентное из ManualResetEvent?

От Olive домашняя страница :

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

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

12
задан Polaris878 30 September 2009 в 23:03
поделиться

2 ответа

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

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

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

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_;
};
13
ответ дан 2 December 2019 в 21:03
поделиться

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

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

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

1
ответ дан 2 December 2019 в 21:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: