首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用std::atomic<>

如何使用std::atomic<>
EN

Stack Overflow用户
提问于 2015-06-10 23:47:27
回答 4查看 67.6K关注 0票数 34

我有一个想要在不同线程中使用的类,我想我可以这样使用std::atomic

代码语言:javascript
复制
class A
{
    int x;

public:
    A()
    {
        x=0;
    }

    void Add()
    {
        x++;
    }

    void Sub()
    {
        x--;
    }     
};

在我的代码中:

代码语言:javascript
复制
  std::atomic<A> a;

在不同的线程中:

代码语言:javascript
复制
  a.Add();

代码语言:javascript
复制
  a.Sub();

但是我得到了一个错误,a.Add()是未知的。我该如何解决这个问题呢?

有没有更好的方法来做到这一点?

请注意,这只是一个示例,我希望确保对类A的访问是线程安全的,所以我不能使用

代码语言:javascript
复制
std::atomic<int> x;

如何使用std::atomic使类成为线程安全的类?

EN

回答 4

Stack Overflow用户

发布于 2015-06-10 23:58:35

您需要使x属性成为原子属性,而不是整个类,如下所示:

代码语言:javascript
复制
class A
{
    std::atomic<int> x;

    public:
      A() {
        x=0;
      }
      void Add() {
        x++;
      }
      void Sub() {
        x--;
      }     
};

您在原始代码中遇到的错误是完全正常的:没有std::atomic<A>::Add方法(请参见here),除非您为std::atomic<A>提供了专门化。

引用您的编辑:您不能通过将其用作std::atomic的模板参数来神奇地确保class A线程的安全。要使其线程安全,您可以将其属性设置为原子属性(如上所述,并且标准库为其提供了专门化),或者使用互斥锁住您的资源。请参阅mutex标头。例如:

代码语言:javascript
复制
class   A
{
  std::atomic<int>      x;
  std::vector<int>      v;
  std::mutex            mtx;

  void  Add() {
    x++;
  }
  void  Sub() {
    x--;
  }

  /* Example method to protect a vector */
  void  complexMethod() {
    mtx.lock();

    // Do whatever complex operation you need here
    //  - access element
    //  - erase element
    //  - etc ...

    mtx.unlock();
  }

  /*
  ** Another example using std::lock_guard, as suggested in comments
  ** if you don't need to manually manipulate the mutex
  */
  void  complexMethod2() {
    std::lock_guard<std::mutex> guard(mtx);

    // access, erase, add elements ...
  }

};
票数 43
EN

Stack Overflow用户

发布于 2015-06-10 23:51:24

将类成员x声明为原子,这样就不必将对象声明为原子:

代码语言:javascript
复制
class A
{  
   std::atomic<int> x;
};
票数 8
EN

Stack Overflow用户

发布于 2015-06-11 00:02:33

可以在对象上使用.运算符来调用其类的成员函数,而不是其他类的成员函数(除非您以这种方式显式编写代码)。

代码语言:javascript
复制
std::atomic<A> a ;
a.Add(); // Here, a does not know what Add() is (a member function of the type parameter)
         // It tries to call Add() method of its own class i.e. std::atomic
         // But std::atomic has no method names Add or Sub

正如@ivanw的答案所提到的,让std::atomic<int>成为您的类的成员,然后使用它。

下面是另一个示例:

代码语言:javascript
复制
template <typename T> class A
{};

class B { public: void hello() { std::cout << "HELLO!!!"; } };

A<B> a ;
a.hello(); // This statement means that call a's hello member function
           // But the typeof(a) which is A does not have such a function
           // Hence it will be an error.
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30761225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档