11
votes

Verrouillage mutex dans un fil et le déverrouillage dans l'autre

Ce code sera correct et portable? XXX

Dans l'application réelle, j'ai trois threads - deux pour ajouter des valeurs à un tableau et un pour les lire. Et j'ai besoin du troisième thread pour afficher le contenu de la matrice juste après l'un des autres threads ajoute un nouvel élément.


0 commentaires

3 Réponses :


14
votes

Ce n'est pas le cas. Si le thread A devient à mutex_unlock (2) avant le thread B de Mutex_Lock (2), vous êtes confronté à un comportement non défini. Vous ne devez pas déverrouiller le mutex d'un autre fil non plus non plus.

le Pthread_mutex_lock Open Group Spécification de la base dit:

Si le type mutex est pthread_mutex_normal [...] si un thread tente de déverrouiller un mutex qu'il n'a pas verrouillé ou un mutex qui est déverrouillé, des résultats de comportement non définis.


2 commentaires

D'accord. Mais qu'en est-il de déverrouiller le mutex qui avait été verrouillé dans un autre fil? Comportement non défini aussi bien?


Comme si cela dit: "Si un fil tente de déverrouiller un mutex qu'il n'a pas verrouillé ... UB"



7
votes

comme Réponse de User562734 dit , la réponse est non - vous ne pouvez pas déverrouiller un fil verrouillé par un autre fil.

Pour obtenir la synchronisation de lecteur / écrivain que vous souhaitez utiliser, vous devez utiliser des variables de condition - pthread_cond_wait () , pthread_cond_signal () et des fonctions associées.


1 commentaires

Les sémaphores sont également parfois utiles pour les situations où vous voulez être capable de "déverrouiller un autre fil de fil". Ils sont en fait une bonne solution de contournement pour le fait que l'utilisation documentée recommandée de pthread_atfork invoque un comportement indéfini. :-)



0
votes

Certaines implémentations permettent de verrouiller et de déverrouiller des threads à être différent.

#include <iostream>
#include <thread> 
#include <mutex> 

using namespace std;

mutex m;

void f() {m.lock();   cout << "f: mutex is locked" << endl;}

void g() {m.unlock(); cout << "g: mutex is unlocked" << endl;}

main()
{
      thread tf(f);    /* start f                           */
      tf.join();       /* Wait for f to terminate           */
      thread tg(g);    /* start g                           */
      tg.join();       /* Wait for g to terminate           */
}


1 commentaires

La mise en œuvre de GCC 4.91 en dit-elle explicitement? Si non et que vous avez votre réponse juste des expériences, alors c'est toujours UB, même si dans ce cas, il semble fonctionner.