Abh*_*yal 1 c++ concurrency multithreading mutex c++17
我有一个由 a 保护的资源类std::mutex,其中访问它的任何方法都必须被锁定并且只能由单个线程执行。如果单独调用各个方法,这效果很好,但现在我需要将这些方法批处理在一起。在这种情况下,互斥锁只需锁定一次,并且这些方法不得再次锁定该互斥锁(否则将导致死锁)。
class Resource {
mutable std::mutex mtx;
int value = 10;
void handleOpStart() const {/* Activate batch mode */ std::cout << "HandleOp activate!"<< std::endl; }
void handleOpEnd() const {/* Deactivate batch mode */ std::cout << "HandleOp deactivate!"<< std::endl; }
public:
int read() const {
std::lock_guard<std::mutex> lock(mtx);
handleOpStart(); auto result = value + 10; handleOpEnd();
return result;
}
void write(int val) {
std::lock_guard<std::mutex> lock(mtx);
handleOpStart(); value = val; handleOpEnd();
}
template<typename Fn>
void batch(Fn fn) {
std::lock_guard<std::mutex> lock(mtx);
handleOpStart();
fn();
handleOpEnd();
}
void print() const {
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Value: " << value << std::endl;
}
};
int main() {
Resource r;
r.print();
r.write(r.read());
r.print();
r.batch([&] {
// will cause deadlock
auto someVal = r.read();
auto someOtherVal = 10 + someVal;
r.write(r.read() + someOtherVal);
});
}
Run Code Online (Sandbox Code Playgroud)
现在我无法从各个方法中删除互斥锁,因为它们可以从外部批处理上下文中单独调用。我无法保留互斥体,因为它们也可以在其中调用。如果我在类中保留一个布尔变量来停用batch函数调用上的互斥体,那么它也会停用从其他线程调用的其他单个函数,再次达到目的。
一种解决方案是写下所有读/写函数的非互斥集,并且仅在批处理上下文中调用它们,而不是在外部。但此类资源访问函数的数量很大,因此增加了维护量并可能引入错误。
寻找替代方案来解决这个问题。