Освобождает ли std::lock_guard мьютекс после создания с параметром std::accept_lock?

Я знаю, что мой вопрос очень похож на этот. Почему std ::lock_guard снимает блокировку после использования std ::accept_lock?, но поведение, которое я вижу, нет. Вот мой код:

      #include <mutex>
#include <iostream>
using namespace std;

std::mutex m;
void fun2();
void fun1() {
    cout << "fun1" << endl;
    std::unique_lock<std::mutex> guard(m);
    cout << "lock mutex" << endl;
    fun2();
    if (guard.owns_lock()) {
        cout << "still holds mutex" << endl;
    }
    else {
        cout << "doesn't hold mutex" << endl;
    }
}
void fun2() {
    std::lock_guard<std::mutex> guard(m, std::adopt_lock);
    cout << "fun2" << endl;
}
int main(int argc, char* argv[]) {
    fun1();
    return 0;
}

И вот результат, который я получаю:

      fun1
lock mutex
fun2
still holds mutex

Ясно, что unique_lock в fun1все еще держит мьютекс. Итак, мой вопрос: "Есть ли std::lock_guard освободить мьютекс после создания с помощью std::adopt_lock вариант? ". Надеюсь, вы все поможете мне прояснить эту ситуацию. Спасибо.

2 ответа

Решение

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

Программа имеет неопределенное поведение.

Вы создали двух охранников, которые оба думают, что владеют mutex и они оба будут unlockЭто. Это УБ.

С использованием m.lock() в fun1 вместо использования охранника было бы одним из способов сделать его поведение определенным.

Другие вопросы по тегам