2016-11-23 14 views
2

Я написал простой код, в котором я беру уникальный_lock и разблокирую мьютекс вместо того, чтобы вызывать разблокировку самой блокировки. Когда первый поток входит в критический раздел и вызывает my_mutex.unlock(), многие другие потоки входят в критический раздел вместе.Вызов разблокировки на мьютексе, связанный с уникальным_блоком, вызывает неопределенное поведение

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

Почему это происходит? Неправильно ли вызывать разблокировку на мьютексе, хранящемся в уникальном_блоке? Благодаря!

ответ

4

UB не вызван явной разблокировкой с использованием std::mutex::unlock, а второй разблокировкой, которая выполняется при выходе из области дескриптором std::unique_lock.

От cppreference.com при вызове std::mutex::unlock:

Мьютексы должен быть заблокирован текущим потоком выполнения, в противном случае поведение не определено.

Решение заключается в не выполнить явное разлочки мьютекса. Вместо этого позвольте std::unique_lock разблокировать себя при уничтожении, как это предусмотрено.

Для случаев, когда замок должен быть выпущен до разрушения, используйте std::unique_lock::unlock, что позволит обеспечить безопасное разрушение. В качестве альтернативы вы можете просто вставить дополнительную область, , например.:

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

Спасибо! На самом деле у меня не было локального мьютекса в моем фактическом коде. Я обновлю код в вопросе. – kwadhwa