J’ai écrit une petite classe pour la synchronisation des threads de Linux (en réalité Android) et de Windows.
Voici l’implémentation Win32 de mon interface:
class SyncObjectWin32 : public SyncObject { private: const HANDLE m_hEvent; public: SyncObjectWin32() : m_hEvent( ::CreateEvent( NULL, FALSE, FALSE ) ) { if( NULL == m_hEvent ) throw core::Exception( "sys::SyncObjectWin32::SyncObjectWin32() - Failed to create event." ); } ~SyncObjectWin32() { ::CloseHandle( m_hEvent ); } void WaitForSignal() { ::WaitForSingleObject( m_hEvent ); } void Signal() { ::SetEvent( m_hEvent ); } };
Le problème est que je ne sais pas quel serait l’équivalent POSIX. Jusqu’ici, j’ai écrit le cours suivant, basé sur cette question SO , mais comme la réponse est incomplète, je ne sais pas comment terminer mon cours:
class SyncObjectPosix { private: pthread_mutex_t m_oMutex; public: SyncObjectPosix() { pthread_mutex_lock( m_oMutex ); // lock mutex bool & signalled = find_signal( condition ); // find predicate signalled = true; // set predicate pthread_mutex_unlock( m_oMutex ); // unlock mutex pthread_cond_signal( condition ); // signal condition variable } ~SyncObjectPosix() { } void WaitForSignal() { pthread_mutex_lock(mutex); // lock mutex bool & signalled = find_signal( condition ); // find predicate while (!signalled) { pthread_cond_timedwait(condition, m_oMutex, timeout); } signalled = false; // reset predicate pthread_mutex_unlock( m_oMutex ); // unlock mutex } void Signal() { } };
L’équivalent POSIX de ce que vous avez décrit est la variable de condition POSIX. Notez que la variable de condition doit toujours être utilisée en paire avec un mutex POSIX, mais plusieurs variables de condition utilisent souvent le même mutex. Par conséquent, si vous n’utilisez pas le mutex exclusivement pour la variable de condition, vous ne devez pas le placer dans la classe. Les mappages par signification dans votre cas entre Win32 et l’API POSIX doivent être:
CreateEvent
-> pthread_cond_init
CloseHandle
-> pthread_cond_destroy
WaitForSingleObject
-> pthread_cond_wait
ou pthread_cond_timedwait
SetEvent
-> pthread_cond_signal
ou pthread_cond_broadcast
Heureusement, il existe beaucoup de documentation à ce sujet, bien que je recommande les principes fondamentaux de programmation POSIX .
Vérifiez également eventfd
. Cela semble presque équivalent à CreateEvent
si vous avez besoin d’un seul consommateur et d’un seul producteur.
CreateEvent
-> eventfd
CloseHandle
-> close
SetEvent
-> write
WaitForSingleObject
-> read
WaitForMultipleObjects
-> select
et read
fd correspondant
Un peu plus de lecture http://www.sourcexr.com/articles/2013/10/26/lightweight-inter-process-signaling-with-eventfd
L’équivalent pthreads de votre code est:
class SyncObjectPosix { private: bool signalled; pthread_mutex_t mutex; pthread_cond_t cond; public: SyncObjectPosix() { signalled = false; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); } ~SyncObjectPosix() { pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); } void WaitForSignal() { pthread_mutex_lock(&mutex); while (!signalled) { pthread_cond_wait(&cond, &mutex); } signalled = false; pthread_mutex_unlock(&mutex); } void Signal() { pthread_mutex_lock(&mutex); signalled = true; pthread_mutex_unlock(&mutex); pthread_cond_signal(&cond); } };
Notre bibliothèque open-source pevents
est une implémentation de cela pour toutes les plateformes. Il s’agit d’un très petit fragment de code C ++ (fichier unique) que vous pouvez simplement append à votre projet existant et accéder à l’API d’événements Windows construite au-dessus des primitives de synchronisation pthreads.
Le plus important est qu’il inclut le support WaitForMultipleObjects
.