7

我已经定义了一个具有std::mutex my_mutex作为其私有成员变量的类。但是当我尝试在从不同线程调用的成员函数中使用它时lock_guard,编译器会抛出很多错误。如果我把这个互斥锁放在课堂之外,它就可以工作。代码如下

class ThreadClass
{
  std::mutex my_mutex;
  public: 
     void addToList(int max, int interval)
    {

      std::lock_guard<std::mutex> guard(my_mutex);
      for (int i = 0; i < max; i++) 
       {
            // Some operation
       }
    }
};


 int main()
 {
    std::thread ct(&ThreadClass::addToList,ThreadClass(),100,1);
    std::thread ct2(&ThreadClass::addToList,ThreadClass(),100,10);
    std::thread ct3(&ThreadClass::print,ThreadClass());

     ct.join();
     ct2.join();
     ct3.join();
  }

如果将相同my_mutex的内容保留在课堂之外,那么它可以正常工作。那么当同一个变量在类中并在线程所作用的成员函数中调用时,它是否像静态成员一样对待?

4

1 回答 1

12

构造std::thread函数复制传递给执行函数的参数。但是std::mutex是不可复制的,ThreadClass如果它有这样的成员,也是不可复制的。

您将一个临时ThreadClass对象传递给std::thread,但您可能希望在所有线程中使用相同的对象。您可以使用std::ref来传递现有对象的引用。以下代码在 GCC 7.1.0 上编译:

#include <thread>
#include <mutex>

class ThreadClass
{
    std::mutex my_mutex;
public: 
    void addToList(int max, int interval)
    {
        std::lock_guard<std::mutex> guard(my_mutex);
        // ...
    }
    void print()
    {
        // ...
    }
};

int main()
{
    ThreadClass obj;
    std::thread ct(&ThreadClass::addToList, std::ref(obj), 100, 1);
    std::thread ct2(&ThreadClass::addToList, std::ref(obj), 100, 10);
    std::thread ct3(&ThreadClass::print, std::ref(obj));

    ct.join();
    ct2.join();
    ct3.join();
}

传递指向对象的指针而不是引用也应该有效:

std::thread ct(&ThreadClass::addToList, &obj, 100, 1);
于 2017-09-19T08:47:30.857 回答