2008-09-27 20 views
1

J'ai récemment vu la lumière du comportement puissant de EventWaitHandle en C# et j'ai décidé de déplacer certaines fonctionnalités dans une application sœur pour faire de même. Le seul problème est que l'application soeur est écrite en C.Comportement EventWaitHandle pour pthread_cond_t

Pas grave, j'utilise des pthreads, qui ont un type de données pthread_cond_t qui permet la signalisation. Ma seule question est la suivante: est-il possible qu'un message soit «signalé» avant que quelque chose ne l'attende?

À l'heure actuelle, mes tests disent non. Autrement dit, si ThreadA déclenche un signal avant que ThreadB n'attende, ThreadB attend indéfiniment. Y at-il un autre type de pthread que je peux utiliser qui se rapproche de la fonctionnalité de l'EventWaitHandle en C#? Un objet est signalé, ce qui signifie que le premier thread à attendre, passera immédiatement, et le mettra à non-marqué.

Envelopper le pthread_cond dans une autre structure de données ne serait pas trop difficile à réaliser. Mais encore une fois, cette fonctionnalité est-elle déjà disponible dans la bibliothèque pthread?

Répondre

4

Si vous utilisez correctement les variables de condition, cela n'aura aucune importance.

Le débit de base de votre code devrait être (en pseudocode):

lock(lockobj); 
while (!signalled) { 
    wait(condvar); 
} 
signalled = false; 
unlock(lockobj); 

du côté d'attente, et:

lock(lockobj); 
signalled = true; 
notify(condvar); 
unlock(lockobj); 

sur le côté de la signalisation. (Bien sûr, l'objet de verrouillage et la variable d'état utilisés doivent être les mêmes des deux côtés.) J'espère que cela aide!

+0

qui pourrait entraîner un blocage si le fil d'attente bloqué avant l'envoi du signal ... ne le ferait-il pas? –

+0

Non, souvenez-vous que lorsque vous attendez sur la condvar, le lockobj est libéré (ceci est fait automatiquement et atomiquement par le fonctionnement des variables de condition). Il est réacquis avant que le thread en attente ne reprenne son exécution. –

+0

Voir http://www.opengroup.org/onlinepubs/009695399/functions/pthread_cond_wait.html sur le comportement de libération de mutex. –

0

Autre réponse (également en pseudo-code) si vous le souhaitez plusieurs signalisations (c'est-à-dire, si deux signalisations sont signalées, deux threads peuvent attendre avant que l'état ne soit à nouveau annulé).

côté d'attente:

lock(lockobj); 
while (signalled != 0) { 
    wait(condvar); 
} 
--signalled; 
unlock(lockobj); 

côté Signalisation:

lock(lockobj); 
++signalled; 
notify(condvar); 
unlock(lockobj); 
0

J'ai fini par envelopper juste un type de condition dans une nouvelle structure et créé quelques fonctions simples à se comporter un peu comme la EventWaitHandle de C#. J'avais besoin de deux mutex pour obtenir un accès sérialisé correct.

Le paramètre cond_mutex est utilisé pour attendre la variable conditionnelle, tandis que le paramètre data_mutex est utilisé pour définir l'état de signalé à non signalé.

Le mode de réinitialisation est identique à C#. AUTO ou MANUEL. Cela permet à event_wait_t de se réinitialiser automatiquement après avoir attendu. Ou laisser le programmeur le faire manuellement avec un appel à event_wait_reset (event_wait_t * ewh);

+0

Non, 1 mutex est suffisant pour ça. Voir mon commentaire (sur le comportement de pthread_cond_wait de mutex-release) pour savoir pourquoi cela fonctionne. (event_wait_reset peut utiliser le même mutex.) –