简体   繁体   English

pthread Windows事件等效问题

[英]pthread windows event equivalent question

I have the following code which replicates the windows manual and auto reset events. 我有以下代码可以复制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;
};

My question surrounds the "optimisation" I've put in place in the set() method where I only call pthread_cond_signal() if the event was unsignalled. 我的问题与我在set()方法中放置的“优化”有关,如果事件未得到通知,则我仅调用pthread_cond_signal() Is this a valid optimisation or have I introduced some subtle flaw by doing so. 这是一个有效的优化,还是我通过这样做引入了一些细微的缺陷。

There's definitely a difference in behavior due to that "optimization" if multiple threads are waiting for the same event. 如果多个线程正在等待同一事件,则由于“优化”,行为上肯定存在差异。 Consider this sequence of events (manual reset mode): 考虑以下事件序列(手动重置模式):

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

With your code, pthread_cond_signal will only be called once (unblocking one of threads 1-3); 使用您的代码,pthread_cond_signal将仅被调用一次(取消阻塞线程1-3中的一个); without the optimization it would be called 3 times (unblocking all 3 of them). 如果不进行优化,则会被调用3次(取消对全部3次的阻止)。

I don't know if that's a "flaw" or not, because I don't know the precise semantics of the Windows API you're emulating. 我不知道这是否是“缺陷”,因为我不知道您要模拟的Windows API的确切语义。

For non-auto-reset events, you only wake one thread on a call to set , but you stop additional threads from blocking. 对于非自动重置事件,您仅在调用set唤醒一个线程,但阻止了其他线程的阻塞。 That doesn't seem sane to me and creates a race condition between waiters and wakers. 在我看来,这似乎并不理智,并在侍应生和唤醒者之间创造了竞争条件。

我会用volatile来对_signalled进行限定,以防止有关该变量的任何聪明的编译器技巧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM