我是线程同步中的新手。我正在阅读许多条件变量的实现,例如win32的boost::threads和pthread。我刚刚用wait/notify/noifyall实现了这个非常简单的监视器,我想它有很多隐藏的问题,我想从更有经验的人那里发现。有什么建议吗?

class ConditionVar
{

public :
    ConditionVar () : semaphore ( INVALID_HANDLE_VALUE ) , total_waiters (0)
    {
        semaphore = ::CreateSemaphoreA ( NULL , 0 /* initial count */ , LONG_MAX /* max count */ , NULL );
    }

    ~ConditionVar ()
    {
        ::CloseHandle ( semaphore ) ;
    }


public :
    template <class P>
    void Wait ( P pred )
    {
        while ( !pred() ) Wait();
    }

public :

    void Wait ( void )
    {
        INTERLOCKED_WRITE_RELEASE(&total_waiters,total_waiters + 1 );
        ::WaitForSingleObject ( semaphore , INFINITE );
    }

    //! it will notify one waiter
    void Notify ( void )
    {
        if ( INTERLOCKED_READ_ACQUIRE(&total_waiters) )
        {
            Wake (1);
        }
    }

    void NotifyAll (void )
    {
        if ( INTERLOCKED_READ_ACQUIRE(&total_waiters) )
        {
            std::cout << "notifying " << total_waiters ;
            Wake ( total_waiters );
        }
    }

protected :
    void Wake ( int count )
    {
        INTERLOCKED_WRITE_RELEASE(&total_waiters,total_waiters - count );
        ::ReleaseSemaphore ( semaphore , count , NULL );
    }

private :
    HANDLE semaphore;
    long    total_waiters;
};

最佳答案

我认为,如果您复制实例,则将发生不好的事情,因为两个拷贝将使用相同的sempahore。这不一定是一件坏事,但是如果语义不完全清楚,可能会使人们感到困惑。

您可以使用类似于boost::noncopyable使用(或使用boost)的方法轻松解决此问题。

09-10 10:03
查看更多