我想了解如何在C++中使用互斥锁来处理对象。我有以下(微不足道的)多线程代码,我正在用它进行速度测试:
struct Rope{
int n, steps, offset;
//std::mutex mut;
Rope() {}
Rope(int n, int steps, int offset) : n(n), steps(steps), offset(offset) {}
void compute(){
double a[n];
for (int i=0; i<n; i++)
a[i] = i + offset;
for (int step=0; step<steps; step++)
for (int i=0; i<n; i++)
a[i] = sin(a[i]);
}
};
void runTest(){
int numRuns = 30;
int n = 10000;
int steps = 10000;
std::vector<Rope> ropes;
std::vector<std::thread> threads;
for (int i=0; i<numRuns; i++)
ropes.push_back(Rope(n, steps, i));
for (auto& r : ropes)
threads.push_back(std::thread(&Rope::compute, r));
for (std::thread& t : threads)
t.join();
}
代码可以原封不动地运行,我的4核机器速度提升了约4倍。当然,我没有将任何东西存储在Rope中,因此无需互斥锁。如果现在假设我确实有一些需要保护的数据,我想在Rope上附加一个互斥锁,并在compute()循环内(例如)调用std::lock_guard。然而,如果取消注释互斥锁,我会得到一堆关于“使用已删除函数”的编译器错误,这些函数包括赋值运算符和复制运算符。我在安全锁定对象方面错过了什么?
Rope
对象,因此不需要互斥锁。当问题没有清楚地解释时,很难说出正确的解决方案。) - James Kanzestd::mutex
不可移动。可以通过在每个Rope
构造函数中默认构造std::mutex
,使Rope
可移动或可复制。或者像James建议的那样,将互斥锁设置为静态变量。哪种方法更适合取决于只有OP在此时才知道。 - Howard Hinnant