如果我在锁定互斥锁之前解锁它可以吗?
Is that OK if I unlock a mutex before I lock it?
我之前写过一些代码,但我发现它的代码风格很糟糕,所以我改变了它。
我更改了 if 块内的 A.unlock。我知道如果 if never 运行 那么这个线程将解锁不属于它自己的互斥锁,然后它会 return 一个未定义的行为。
我的问题是,如果它 return 是未定义的行为,这里的逻辑是否仍然有效?因为如果线程 t1 没有锁,t1 解锁互斥量 A 将 return 取消定义行为并且互斥量仍将由持有它的线程持有,对吗?并且不会影响这段代码中的其他逻辑。
我的旧代码与我将解锁部分放在 if 块中一样。所以这就是为什么我很好奇这是如何工作的。
mutex A;
if(something)
{
A.lock();
}
A.unlock();
你应该考虑使用 std::lock_guard
:
mutex A;
if (something)
{
lock_guard<mutex> lock(A);
}
在互斥量上调用 unlock 时,互斥量必须由当前线程拥有,否则行为未定义。未定义的行为意味着任何事情都可能发生,包括程序 运行 正确显示、程序崩溃或其他地方的内存损坏以及问题直到后来才可见。
通常不直接使用互斥量;其他标准之一 类 (如 std::unique_lock
or std::lock_guard
用于管理它。那么您就不必担心解锁互斥锁。
这是一个 undefined behavior 来解锁一个你还没有锁定的 mutex
。它可能会在某些情况下工作很多次,但总有一天它会崩溃并表现不同。
你可以在你的情况下使用 lock_guard
而忘记 lock/unlock
std::lock_guard<std::mutex> lock(A);
ISO C++ 标准在 [thread.mutex.requirements.mutex]
(我强调的)中对此事有这样的说法:
The expression m.unlock()
shall be well-formed and have the following semantics:
Requires: The calling thread shall own the mutex.
这意味着你所做的是违反标准的,因此是未定义的。它 可能 有效,或者它可能会在播放 derisive_maniacal_laughter.mp3
文件时删除您的所有文件:-)
底线,不要这样做。
我也不会将 unlock
放在循环中,因为现代 C++ 具有更高级别的机制来处理资源的自动释放。在这种情况下,它是一个锁卫:
std::mutex mtxProtectData; // probably defined elsewhere (long-lived)
: : :
if (dataNeedsChanging) {
std::lock_guard<std::mutex> mtxGuard(mtxProtectData);
// Change data, mutex will unlock at brace below
// when mtxGuard goes out of scope.
}
我之前写过一些代码,但我发现它的代码风格很糟糕,所以我改变了它。
我更改了 if 块内的 A.unlock。我知道如果 if never 运行 那么这个线程将解锁不属于它自己的互斥锁,然后它会 return 一个未定义的行为。 我的问题是,如果它 return 是未定义的行为,这里的逻辑是否仍然有效?因为如果线程 t1 没有锁,t1 解锁互斥量 A 将 return 取消定义行为并且互斥量仍将由持有它的线程持有,对吗?并且不会影响这段代码中的其他逻辑。 我的旧代码与我将解锁部分放在 if 块中一样。所以这就是为什么我很好奇这是如何工作的。
mutex A;
if(something)
{
A.lock();
}
A.unlock();
你应该考虑使用 std::lock_guard
:
mutex A;
if (something)
{
lock_guard<mutex> lock(A);
}
在互斥量上调用 unlock 时,互斥量必须由当前线程拥有,否则行为未定义。未定义的行为意味着任何事情都可能发生,包括程序 运行 正确显示、程序崩溃或其他地方的内存损坏以及问题直到后来才可见。
通常不直接使用互斥量;其他标准之一 类 (如 std::unique_lock
or std::lock_guard
用于管理它。那么您就不必担心解锁互斥锁。
这是一个 undefined behavior 来解锁一个你还没有锁定的 mutex
。它可能会在某些情况下工作很多次,但总有一天它会崩溃并表现不同。
你可以在你的情况下使用 lock_guard
而忘记 lock/unlock
std::lock_guard<std::mutex> lock(A);
ISO C++ 标准在 [thread.mutex.requirements.mutex]
(我强调的)中对此事有这样的说法:
The expression
m.unlock()
shall be well-formed and have the following semantics:Requires: The calling thread shall own the mutex.
这意味着你所做的是违反标准的,因此是未定义的。它 可能 有效,或者它可能会在播放 derisive_maniacal_laughter.mp3
文件时删除您的所有文件:-)
底线,不要这样做。
我也不会将 unlock
放在循环中,因为现代 C++ 具有更高级别的机制来处理资源的自动释放。在这种情况下,它是一个锁卫:
std::mutex mtxProtectData; // probably defined elsewhere (long-lived)
: : :
if (dataNeedsChanging) {
std::lock_guard<std::mutex> mtxGuard(mtxProtectData);
// Change data, mutex will unlock at brace below
// when mtxGuard goes out of scope.
}