2016-11-22 42 views
0

这是一段极好的代码,它解决了如何在对象的成员函数上使用锁定。如何锁定使用带初始化列表构造函数的类的成员函数

#include <thread> 
#include <mutex> 
#include <iostream> 

class Foo 
{ 
public: 
     void increment() 
     { 
     for (int i = 0; i < 10000000; ++i) 
     { 
      std::lock_guard<std::mutex> lock(mtx); //lock mtx 
       ++x; 

      // mtx is automatically released when lock 
      // goes out of scope -> RAII 
     } 
    } 

    void decrement() 
    { 
      for (int i = 0; i < 10000000; ++i) 
      { 
       std::lock_guard<std::mutex> lock(mtx); //lock mtx 
       --x; 

       // mtx is automatically released when lock 
       // goes out of scope -> RAII 
      } 
     } 

     static int x; 
     static std::mutex mtx; 
    }; 

    int Foo::x = 0; 
    std::mutex Foo::mtx; 

    int main() 
    { 
     std::thread t1(&Foo::increment, Foo()); 
     std::thread t2(&Foo::decrement, Foo()); 

     t1.join(); 
     t2.join(); 

     std::cout << Foo::x; 
    } 

我的问题是,如果构造函数有一个数据成员初始化列表如何实现这个。可能吗?

+0

我*想*你的意思是如何处理初始化一些非静态成员'y',你想用通常是'Foo():y(x){}'的东西来初始化。那是对的吗 ? – WhozCraig

+0

顺便说一句,对于'int',你可以使用'std :: atomic'而不是'mutex'。 – Jarod42

回答

1

如果Foo具有数据成员初始化列表,并且每个线程都有自己的Foo类实例,则不需要额外的锁定。 Member initialization list指定直接和虚拟基本子对象和非静态数据成员的初始值设定项。

您只需要一个lock来控制线程之间共享状态的一致性。像您样本中的静态Foo::x一样。

相关问题