Porting Windows événement de réinitialisation manuelle à Linux?
Est-il une solution plus facile dans le portage de windows événement de réinitialisation manuelle à pthread,
qu'un pthread conditionnelle de la variable + pthread mutex + un drapeau si l'événement est défini ou indéfini?
source d'informationauteur
Vous devez vous connecter pour publier un commentaire.
Pthreads sont bas niveau des constructions. Non, il n'est pas un simple mécanisme;
pthread_cond__*
est conceptuellement similaire à un événement de réinitialisation automatique. Attention,pthread_cond_wait
peut avoir des parasites de réveils, de sorte qu'il ne devrait jamais être utilisé sans une sorte de externe du pavillon quelle que soit la situation.La construction de votre propre, ne devrait pas être trop dur, mais.
Cela peut ne pas convenir à votre utilisation, vous aurez souvent un autre verrou que vous voulez les utiliser à la place de
ev->mutex
mais c'est l'essentiel de la façon dont il est généralement utilisé.Vous pouvez facilement mettre en œuvre de réinitialisation manuelle des événements avec des tuyaux:
événement est déclenché état -> il y a quelque chose à lire à partir de la pipe
SetEvent -> write()
ResetEvent -> read()
WaitForMultipleObjects -> poll() (ou sélectionnez()) pour la lecture de
la "SetEvent" opération doit écrire quelque chose (par exemple, 1 octet de valeur) juste pour mettre le tuyau dans la non-vides de l'état, de sorte ultérieure opération "d'Attente", qui est, poll() pour les données disponibles pour la lecture ne va pas bloquer.
La "ResetEvent" l'opération va lire les données écrites pour s'assurer de la pipe est à nouveau vide.
La lecture de la fin du tuyau doit être faite de non-blocage, de sorte que la tentative de réinitialisation (à lire à partir de) déjà l'événement de réinitialisation (tube vide) l'habitude de bloc - fcntl(pipe_out, F_SETFL, O_NONBLOCK)
Depuis il y a peut être plus de 1 SetEvents avant la ResetEvent, vous devriez le code afin qu'il se lise comme autant d'octets qu'il y a dans le tuyau:
Remarque que l'attente de l'événement n'est pas lu de la pipe et donc de "l'événement" restera dans déclenchée état jusqu'à ce que l'opération de réinitialisation.
Non il n'existe pas de solution facile, mais le code suivant fera l'affaire:
Lors de l'appel de signal(), l'événement se passe dans l'état signalé et tous les thread en attente d'exécution. L'évènement sera de rester dans l'état signalé et tout le thread qui appelle wait() ne se feront pas attendre. Un appel à reset() met l'événement retour à l'état non signalé.
La signalCounter est-il dans le cas où vous faites un rapide signal/reset pour réveiller les threads en attente.
Je préfère la pipe approche, parce que souvent, on n'a pas besoin seulement d'un événement d'attendre, mais de multiples objets (p. ex.
WaitForMultipleObjects(...)
. Et avec l'aide de tuyaux, on pourrait facilement remplacer les fenêtresWaitForMultipleObjects
appel avecpoll(...)
select
pselect
etepoll
.Il y avait un peu de poids à la méthode pour le processus de synchronisation appelé
Futex
(Fast Userspace système de Verrouillage d'appel). Il y avait une fonctionfutex_fd
pour obtenir un ou plusieurs descripteurs de fichier pour futexes. Ce descripteur de fichier, de concert avec d'autres représentant réel des fichiers, des périphériques, des sockets ou pourrait se passait àselect
poll
ouepoll
. Malheureusement, il a été retiré à partir du noyau. De sorte que les tuyaux ficelles restent la seule installation pour ce faire:Je pense que des Événements de Windows sont plus proches d'un sémaphore. I. e. pour la remise à zéro automatique, vous pouvez utiliser un sémaphore binaire et le sem_timedwait() fonction.
Nous recherchions une solution similaire pour le port certains lourdement multithread code C++ à partir de Windows à Linux, et a fini par écrire un open source, MIT sous licence Win32 Événements pour Linux bibliothèque. Il devrait être la solution que vous cherchez, et a été largement validée pour la performance et la consommation de ressources.
Il met en oeuvre manuel et auto-réinitialisation des événements, et à la fois le
WaitForSingleObject
etWaitForMultipleObject
fonctionnalités.Nous (divulgation complète: je travaille à NeoSmart Technologies) a écrit un open source (sous licence MIT) bibliothèque appelée pevents qui met en œuvre WIN32 manuel et auto-reset événements sur POSIX, et comprend à la fois WaitForSingleObject et WaitForMultipleObjects clones. On a vu certains d'adoption depuis (il est utilisé dans Steam sur Linux/Mac) et fonctionne assez bien.
Bien que je serais personnellement vous conseillons d'utiliser POSIX multithreading et la signalisation des paradigmes lors du codage sur POSIX machines, pevents vous donne un autre choix si vous en avez besoin.