我是线程同步中的新手。我正在阅读许多条件变量的实现,例如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)的方法轻松解决此问题。