pthread windows事件等效问题

时间:2010-03-08 12:16:33

标签: c++ windows multithreading events pthreads

我有以下代码复制Windows手动和自动重置事件。

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 个答案:

答案 0 :(得分:1)

如果多个线程正在等待同一事件,那么由于“优化”,行为肯定存在差异。考虑这一系列事件(手动重置模式):

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的精确语义。

答案 1 :(得分:0)

对于非自动重置事件,您只需在调用set时唤醒一个线程,但您可以阻止其他线程阻塞。这对我来说似乎并不理智,并在服务员和妓女之间造成了竞争条件。

答案 2 :(得分:-1)

我使用volatile来限定_signalled,以防止任何关于该变量的聪明的编译器技巧。