2016-11-23 2 views
2

Ich habe einen einfachen Code geschrieben, wo ich einen unique_lock nehme und den Mutex freischalte, anstatt Entsperrung auf dem Schloss selbst aufzurufen. Wenn der erste Thread den kritischen Abschnitt betritt und my_mutex.unlock() aufruft, werden viele andere Threads gemeinsam in den kritischen Abschnitt eingefügt.Aufrufen von Entsperren auf einem Mutex, der mit einem unique_lock verknüpft ist, verursacht undefiniertes Verhalten

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

Warum passiert das? Ist es falsch, Entsperren auf einem Mutex aufzurufen, der von einem unique_lock gehalten wird? Vielen Dank!

Antwort

4

Die UB wird nicht durch das explizite Entsperren mithilfe von std::mutex::unlock verursacht, sondern durch das zweite Entsperren, das vom std::unique_lock Destruktor beim Beenden des Bereichs ausgeführt wird.

Von cppreference.com wenn std::mutex::unlock Aufruf:

Der Mutex durch den aktuellen Thread der Ausführung gesperrt werden muss, sonst ist das Verhalten nicht definiert.

Die Lösung ist nicht die expliziten Entriegelungs auf der Mutex auszuführen. Stattdessen lassen Sie die std::unique_lock entsperren sich bei der Zerstörung wie vorgesehen.

Für Fälle, in denen das Schloss vor der Zerstörung freigegeben werden muss, verwenden Sie std::unique_lock::unlock, die eine sichere Zerstörung ermöglichen. Alternativ können Sie einfach einen zusätzlichen Bereich einfügen, z. B. .:

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

Vielen Dank! Eigentlich hatte ich keinen lokalen Mutex in meinem eigentlichen Code. Ich werde den Code in der Frage aktualisieren. – kwadhwa

Verwandte Themen