Я новичок в синхронизации потоков. Я читал много реализаций условных переменных, таких как boost :: threads и pthread для win32. Я просто реализовал этот довольно простой монитор с 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;
};
это использует библиотеку ускорения? – lsalamon
ну, я просто скопировал макросы INTERLOCKED_READ_ACQUIRE/INTERLOCKED_WRITE_RELEASE, чтобы читать/записывать счетчики в память с помощью заграждений памяти. –
@ Isalamon: Я думаю, он хочет катить свой собственный класс condvar, используя Boost.Threads для вдохновения. –