在代码的其他部分使用 lock_gard 和不使用它的相同互斥锁是否安全
is it safe to use the same mutex with lock_gard and without it in other parts of code
我有命名空间,在该命名空间下,不同线程将调用 func1 和 func2。
#include<thread>
namespace test{
std::mutex mu;
void func1(){
std::lock_guard<mutex>lock(mu);
//the whole function needs to be protected
}
void func2() {
mu.lock();
//some code that should not be executed when func1 is executed
mu.unlock();
//some other code
}
}
使用此互斥量(一次与 lock_guard 及其外部)来保护这些关键部分是否安全?如果不是如何实现这个逻辑?
当至少涉及两个 mutex
或单个 mutex
由于某种原因没有永远解锁时,就会发生死锁。
第二个函数的唯一问题是,在异常情况下锁不会被释放。
您可以简单地使用 lock_guard
或任何其他被销毁的东西(并解锁 dtor 的互斥量)来避免像您对第一个函数所做的那样的情况。
lock_guard
所做的一切都是为了保证在破坏时解锁。当函数可以采用多条路径(想想异常!)而不是必需时,让代码正确是很方便的。此外,它建立在 "regular" lock()
和 unlock()
函数之上。综上,安全。
是的,您可以在不同的函数中将不同的守卫实例(例如 lock_guard、unique_lock 等)与 std::mutex
有效地混合和匹配。我偶尔 运行 遇到的一种情况是,当我想对大多数方法使用 std::lock_guard
时,但是 std::condition_variable
的使用期望其 wait
方法使用 std::unique_lock
。
为了详细说明 Oblivion 所说的内容,我通常会在函数中引入一个新的作用域块,以便 std::lock_guard
的用法保持一致。示例:
void func2() {
{ // ENTER LOCK
lock_guard<std::mutex> lck;
//some code that should not be executed when func1 is executed
} // EXIT LOCK
// some other (thread safe) code
}
使用上述模式的优点是,如果在锁定代码的临界区内有任何异常抛出,lck
的析构函数仍将被调用,从而解锁互斥量.
我有命名空间,在该命名空间下,不同线程将调用 func1 和 func2。
#include<thread>
namespace test{
std::mutex mu;
void func1(){
std::lock_guard<mutex>lock(mu);
//the whole function needs to be protected
}
void func2() {
mu.lock();
//some code that should not be executed when func1 is executed
mu.unlock();
//some other code
}
}
使用此互斥量(一次与 lock_guard 及其外部)来保护这些关键部分是否安全?如果不是如何实现这个逻辑?
当至少涉及两个 mutex
或单个 mutex
由于某种原因没有永远解锁时,就会发生死锁。
第二个函数的唯一问题是,在异常情况下锁不会被释放。
您可以简单地使用 lock_guard
或任何其他被销毁的东西(并解锁 dtor 的互斥量)来避免像您对第一个函数所做的那样的情况。
lock_guard
所做的一切都是为了保证在破坏时解锁。当函数可以采用多条路径(想想异常!)而不是必需时,让代码正确是很方便的。此外,它建立在 "regular" lock()
和 unlock()
函数之上。综上,安全。
是的,您可以在不同的函数中将不同的守卫实例(例如 lock_guard、unique_lock 等)与 std::mutex
有效地混合和匹配。我偶尔 运行 遇到的一种情况是,当我想对大多数方法使用 std::lock_guard
时,但是 std::condition_variable
的使用期望其 wait
方法使用 std::unique_lock
。
为了详细说明 Oblivion 所说的内容,我通常会在函数中引入一个新的作用域块,以便 std::lock_guard
的用法保持一致。示例:
void func2() {
{ // ENTER LOCK
lock_guard<std::mutex> lck;
//some code that should not be executed when func1 is executed
} // EXIT LOCK
// some other (thread safe) code
}
使用上述模式的优点是,如果在锁定代码的临界区内有任何异常抛出,lck
的析构函数仍将被调用,从而解锁互斥量.