Je suis nouveau dans la synchronisation de threads. Je lisais de nombreuses implémentations de variables conditionnelles, comme boost :: threads et pthread pour win32. J'ai juste implémenté ce moniteur assez simple avec wait/notify/noifyall, et je suppose qu'il y a beaucoup de problèmes cachés, que j'aimerais découvrir chez des gens plus expérimentés. Toute suggestion?Qu'est-ce qui est dangereux dans ce fil extrêmement simple Mise en œuvre du moniteur?
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;
};
cela utilise la bibliothèque boost? – lsalamon
bien, je viens de copier les macros INTERLOCKED_READ_ACQUIRE/INTERLOCKED_WRITE_RELEASE, pour lire/écrire les compteurs en mémoire en utilisant des barrières de mémoire. –
@Isalamon: Je pense qu'il veut rouler sa propre classe de condvar en utilisant Boost.Threads pour l'inspiration. –