我已经定义了一个以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
被排除在课堂之外,那么它可以正常工作。因此,当同一个变量在类中并在一个线程作用的成员函数内调用时,它是否像静态成员一样对待?
答案 0 :(得分:4)
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);