Pthread Windows событие эквивалентный вопрос - PullRequest
2 голосов
/ 08 марта 2010

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

class event
{
public:
    event( bool signalled = false, bool ar = true ) :
        _auto( ar ),
        _signalled( signalled )
    {
        pthread_mutex_init( &_mutex, NULL );
        pthread_cond_init( &_cond, NULL );
    }

    ~event()
    {
        pthread_cond_destroy( &_cond );
        pthread_mutex_destroy( &_mutex );
    }

    void set()
    {
        pthread_mutex_lock( &_mutex );

        // only set and signal if we are unset
        if ( _signalled == false )
        {
            _signalled = true;

            pthread_cond_signal( &_cond );
        }

        pthread_mutex_unlock( &_mutex );
    }

    void wait()
    {
        pthread_mutex_lock( &_mutex );

        while ( _signalled == false )
        {
            pthread_cond_wait( &_cond, &_mutex );
        }

        // if we're an autoreset event, auto reset
        if ( _auto )
        {
            _signalled = false;
        }

        pthread_mutex_unlock( &_mutex );
    }

    void reset()
    {
        pthread_mutex_lock( &_mutex );

        _signalled = false;

        pthread_mutex_unlock( &_mutex );
    }

private:
    pthread_mutex_t _mutex;
    pthread_cond_t _cond;
    bool _signalled;
    bool _auto;
};

Мой вопрос окружает «оптимизацию», которую я применил в методе set(), когда я вызываю pthread_cond_signal(), только если событие не было сигнализировано. Это действительная оптимизация, или я сделал некоторый тонкий недостаток, сделав это.

Ответы [ 3 ]

1 голос
/ 08 марта 2010

Существует определенная разница в поведении из-за этой «оптимизации», если несколько потоков ожидают одного и того же события. Рассмотрим эту последовательность событий (режим ручного сброса):

thread 1 - wait
thread 2 - wait
thread 3 - wait
thread 4 - set
thread 4 - set
thread 4 - set
thread 4 - reset

С вашим кодом pthread_cond_signal будет вызываться только один раз (разблокировка одного из потоков 1-3); без оптимизации он будет вызван 3 раза (разблокировка всех 3 из них).

Я не знаю, является ли это "недостатком" или нет, потому что я не знаю точную семантику Windows API, которую вы эмулируете.

0 голосов
/ 17 сентября 2011

Для событий без автоматического сброса вы вызываете только один поток при вызове на set, но блокируете дополнительные потоки. Это не кажется мне вменяемым и создает условия для гонок между официантами и пекарями.

0 голосов
/ 08 марта 2010

Я бы квалифицировал _signalled как volatile, чтобы предотвратить любые хитрые уловки компилятора в отношении этой переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...