c++ - C++ 11 原子对象的执行也是原子的吗?

标签 c++ multithreading c++11 thread-safety atomic

我有一个对象,它的所有函数都应该按顺序执行。 我知道可以使用像

这样的互斥锁来做到这一点
#include <mutex> 

class myClass {
private:
    std::mutex mtx;
public:
    void exampleMethod();
};

void myClass::exampleMethod() {
    std::unique_lock<std::mutex> lck (mtx); // lock mutex until end of scope

    // do some stuff
}

但是使用这种技术,在 exampleMethod 中调用其他互斥锁定方法后会发生死锁。

所以我正在寻找更好的解决方案。 默认的 std::atomic 访问是顺序一致的,因此不可能同时读取和写入该对象,但是现在当我访问我的对象并调用方法时,整个函数调用也是原子的还是类似的

object* obj = atomicObj.load(); // read atomic
obj.doSomething(); // call method from non atomic object;

如果是的话,有没有比用互斥体锁定大多数函数更好的方法?

最佳答案

停下来想想什么时候你确实需要锁定互斥锁。如果您有一些在许多其他函数中调用的辅助函数,它可能不应该尝试锁定互斥体,因为调用者已经拥有了。

如果在某些上下文中它没有被另一个成员函数调用,因此确实需要锁定,请提供一个实际执行此操作的包装函数。有 2 个版本的成员函数(公共(public) foo() 和私有(private) fooNoLock())的情况并不罕见,其中:

public:
void foo() {
    std::lock_guard<std::mutex> l(mtx);
    fooNoLock();
}

private:
void fooNoLock() {
    // do stuff that operates on some shared resource...
}

根据我的经验,递归互斥体是 code smell这表明作者并没有真正了解这些函数的使用方式 - 并非总是错误,但当我看到一个错误时,我会产生怀疑。

至于原子操作,它们实际上只能应用于小型算术操作,例如递增整数或交换 2 个指针。这些操作并不是自动原子的,但是当您使用原子操作时,它们就可以用于这些事情。您当然不能对单个原子对象上的两个单独的操作抱有任何合理的期望。在操作之间任何事情都可能发生。

关于c++ - C++ 11 原子对象的执行也是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35667881/

相关文章:

c++ - 获取对 lambda 捕获值的引用

c++ - transform_primary() 和 collat​​e_byname()

java - 解决 Hibernate 在多线程应用程序中的错误

c++ - 为什么 c++11 std::array 使用模板来初始化 max_size 而不是构造函数?

Android - 更改 Activity 时的多线程问题

c# - 如何在 .net 中找到当前线程的最大堆栈大小?

c++ - 计算独特项目的更好方法

c++ - 二维数组问题-我收到错误 : expression must have pointer-to-object type (opencv, CUDA)

c++ - 如何对数组 int (*&Test)[10] 进行赋值?

c++ - 创建一个链表,每个节点指向另一个链表