2016-11-23 1 views
2

J'ai écrit un code simple où je prends un unique_lock et déverrouille le mutex au lieu d'appeler le déverrouillage sur le verrou lui-même. Lorsque le premier thread entre dans la section critique et appelle my_mutex.unlock(), de nombreux autres threads entrent ensemble dans la section critique.L'appel déverrouillé sur un mutex associé à un unique_lock provoque un comportement indéfini

std::mutex my_mutex; 
void sample() { 
    std::unique_lock<std::mutex> lock(my_mutex); 
    // Critical section 
    my_mutex.unlock(); 
} 

Pourquoi cela se produit-il? Est-ce mal d'appeler le déverrouillage sur un mutex tenu par un unique_lock? Merci!

Répondre

4

L'UB n'est pas causé par le déverrouillage explicite à l'aide de std::mutex::unlock, mais par le deuxième déverrouillage effectué par le destructeur std::unique_lock à la sortie de l'étendue.

De cppreference.com lorsque vous appelez std::mutex::unlock:

Le mutex doit être verrouillé par le thread courant d'exécution, sinon, le comportement est indéfini.

La solution est de ne pas effectuer le déverrouillage explicite sur le mutex. Au lieu de cela laissez le std::unique_lock se déverrouiller lors de la destruction comme prévu.

Pour les cas où la serrure doit être libérée avant la destruction, utiliser std::unique_lock::unlock qui permettra une destruction sans danger. Alternativement, vous pouvez simplement insérer une portée supplémentaire, par ex.:

void sample() { 
    // Before. 
    { 
     std::unique_lock<std::mutex> lock(my_mutex); 
     // Critical section. 
    } 
    // After. 
} 
+0

Merci! En fait, je n'avais pas de mutex local dans mon code actuel. Je vais mettre à jour le code dans la question. – kwadhwa