在类中使用std::mutex作为成员变量

12

我定义了一个类,其中私有成员变量是 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不在类中,则它可以正常工作。那么当相同的变量在类内部并在成员函数中被线程操作时,它是否像静态成员一样处理?


为什么要尝试将临时对象作为参数传递给线程? - David Haim
1个回答

15
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);

传递指向对象的指针是可行的。但是将 std::ref(obj) 用于参数化的成员函数 addToList 并没有起作用。 - Prashant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接