- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在使用类时,我试图更好地理解 std::mutex
、std::lock_guard
、std::unique_lock
.
对于初学者来说,我知道 lock_guard
和 unique_lock
之间的区别:我知道 lock_guard
仅在构造时锁定互斥体,这是一个在类成员函数中使用它时的首选用法如下:
class Foo {
std::mutex myMutex;
public:
void someFunc() {
std::lock_guard<std::mutex> guard( myMutex );
// code
}
};
如上面所示,带有类成员 myMutex 的 lock_guard 将在函数 Foo::someFunc()
的作用域的开头被锁定,然后在代码离开作用域后解锁,因为lock_guard
和 mutex
的析构函数。
我还了解 unique_lock
允许您多次锁定和解锁互斥锁。
我的问题是关于类的设计;如果我希望互斥体被锁定在类的构造函数中,那么当构造函数超出范围时不要将其解锁,而是在调用类的析构函数时解锁。 .
class Foo {
std::mutex myMutex;
public:
Foo() {
// lock mutex here;
}
~Foo() {
// unlock mutex here;
}
};
以上能否实现;如果是的话怎么办?
在上面的最后一个例子中,我不确定的是:类的构造函数中是否使用了lock_guard;在构造函数离开作用域后,或者当类的对象超出作用域时调用类的析构函数时,它会超出作用域吗?我喜欢尝试模仿所示的第二个示例的所需行为。
最佳答案
在我发布这个问题之后:我做了更多的研究和一些尝试和错误。因此,我选择了不同的实现和解决方案。
我最终使用了 std::shared_mutex
和 std:shared_lock
,而不是我最初提议的。
因此,在我的类的 header 中,我没有保存或存储任何互斥体
。现在在我类(class)的 cpp 文件中。我正在使用静态全局 shared_mutex
所以我的类现在看起来像这样:
Foo.cpp
#include "Foo.h"
#include <mutex>
std::mutex g_mutex;
Foo::Foo() {
// code not locked
{ // scope of guard
std::lock_guard<std::mutex> lock( g_mutex );
// code to lock
} // end scope destroy guard unlock mutex
// other class code
}
Foo::someFunc() {
// Code to lock
std::lock_guard<std::mutex> lock( g_mutex );
}
我发现了为什么它对我来说不能正常工作。在我的类的构造函数中,它从其父类或基类调用函数。然后,父类或基类调用此类的静态成员,并且此类的静态成员函数也在同一个互斥锁上使用 lock_guard。
发现问题后;我有两个选择。我可以使用 2 个独立的互斥体,一个专门用于构造函数,另一个专门用于静态方法。经过一番思考后,我发现如果我使用 2,并且我会阻止完整的构造函数,那么当前的锁和互斥锁将不会超出范围,直到类实例被销毁;然而,类的生命周期将几乎是应用程序的整个生命周期。然后,如果我在静态方法中使用第二个互斥锁和锁保护,则在现有锁保护周围包裹另一个 lock_guard 将是多余的。所以我得出的结论是,我需要为需要被互斥体阻塞的代码创建一个作用域 block { }
,以便在该部分超出作用域后可以解锁,然后构造函数可以自由调用静态方法,并且可以重用与现在相同的互斥锁。该类现在可以正常工作,并且不会崩溃,也不会抛出不应发生的异常。
关于c++ - 在类中正确使用 mutex、lock_guard、unique_lock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49636732/
我有一个函数 foo在多个线程中运行(std::thread t([&]() { foo(a); }): void foo(int a) { if (x && y != a) {
我有包含在 shared_ptr 中的资源“resource”,我想从其他线程访问它。当我这样做时: // foo.h class Foo{ public: std::shared_ptr G
这个问题在这里已经有了答案: Is a copy-on-return operation executed prior or after lock_guard destructor? [duplica
我写了 3 个互斥类 TMutex、TCondition 和 TSpinLock 都有一个 void lock() 和一个 void unlock() 成员。现在我想对它们使用 std::lock_g
一个线程有如下的控制流程: mutex.lock() if (condition) { // do synced things mutex.unlock(); // do pa
我有一个数组,其中每个条目都是一个链表。为了避免在访问链接列表时出现同步问题,我为每个条目添加了一个互斥量。 我的问题是,我能否将循环的每次迭代中对 lock 和 unlock 的以下调用转换为一个
我刚刚了解到 std::lock_guard 我想知道为什么它是一个模板。 到现在我只看到std::lock_guard与 std::mutex在尖括号内。 最佳答案 使用 std::lock_gua
我刚刚了解到 std::lock_guard 我想知道为什么它是一个模板。 到现在我只看到std::lock_guard与 std::mutex在尖括号内。 最佳答案 使用 std::lock_gua
如果我在 lock_guard 下有一些代码,例如: std::thread t([&]() { std::lock_guard lock(m); // some simple ope
我正在使用一些多线程代码(使用并发数据结构),其中一部分需要我锁定一组互斥锁。对于我的实现,我使用了一个 lock_guards vector ,因为我不一定知道我需要锁定多少个互斥锁,而且我可能会遇
我认为这是关于左值实例化排序的更普遍的问题。 简而言之,这安全吗?: void func1() { std::lock_guard lock( mutex ); //do some s
https://en.cppreference.com/w/cpp/thread/lock_guard (constructor) constructs a lock_guard, optionall
[无需点击链接即可理解问题]。 我在this answer中结合了单例模式的实现, 连同 this other answer 的同步文件写入. 然后我想看看SynchronizedFile的接口(in
我试图在以下代码中锁定我的互斥量列表,以便一次只有一个线程可以搜索、解锁、锁定或修改它。 #include #include #include #include #include #incl
编辑: 看起来,问题是我实际上并没有创建一个 lock_guard 的本地实例,而只是一个匿名的临时实例,它立即再次被销毁,如下面的评论所指出的。 Edit2:启用 clang 的线程清理器有助于在运
我有简单的代码:第一个线程将 std::strings 推送到 std::list,第二个线程弹出 std::strings 从这个 std::list。所有 std::list 的操作都受到 std
我目前正在研究 Google 的 Filament 作业系统。你可以找到源代码 here .让我感到困惑的部分是这个 requestExit() 方法: void JobSystem::request
这个问题在这里已经有了答案: C++ return value created before or after auto var destruction? (2 个答案) in C++ which
在下面的代码中,bad 方法编译失败,但是 good 方法没有。为什么提供对 this 的显式引用在这里有所不同? #include class Foo { private: std::mut
我有一个函数,语句 foo 应该在 lock_guard 下执行,但只有当一个指向 mutex 对象的指针被提供给函数作为参数。否则 foo 不必由 lock_guard 保护。 我不能在 if 中使
我是一名优秀的程序员,十分优秀!