gpt4 book ai didi

c++ - 确保线程不会两次锁定互斥体?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:15:06 25 4
gpt4 key购买 nike

假设我有一个线程运行成员方法,例如下面的示例中的 runController:

class SomeClass {
public:
SomeClass() {
// Start controller thread
mControllerThread = std::thread(&SomeClass::runController, this)
}

~SomeClass() {
// Stop controller thread
mIsControllerThreadInterrupted = true;
// wait for thread to die.
std::unique_lock<std:::mutex> lk(mControllerThreadAlive);
}

// Both controller and external client threads might call this
void modifyObject() {
std::unique_lock<std::mutex> lock(mObjectMutex);
mObject.doSomeModification();
}
//...
private:
std::mutex mObjectMutex;
Object mObject;

std::thread mControllerThread;
std::atomic<bool> mIsControllerInterrupted;
std::mutex mControllerThreadAlive;

void runController() {
std::unique_lock<std::mutex> aliveLock(mControllerThreadAlive);
while(!mIsControllerInterruped) {
// Say I need to synchronize on mObject for all of these calls
std::unique_lock<std::mutex> lock(mObjectMutex);
someMethodA();
modifyObject(); // but calling modifyObject will then lock mutex twice
someMethodC();
}
}
//...
};

runController 中的部分(或全部)子例程需要修改线程之间共享并由互斥锁保护的数据。其中一些(或全部)也可能被需要修改此共享数据的其他线程调用。

拥有 C++11 的所有荣耀,我如何确保没有线程会两次锁定互斥量?

现在,我将 unique_lock 引用作为参数传递给方法,如下所示。但这看起来很笨重,难以维护,可能是灾难性的,等等......

void modifyObject(std::unique_lock<std::mutex>& objectLock) {

// We don't even know if this lock manages the right mutex...
// so let's waste some time checking that.
if(objectLock.mutex() != &mObjectMutex)
throw std::logic_error();

// Lock mutex if not locked by this thread
bool wasObjectLockOwned = objectLock.owns_lock();
if(!wasObjectLockOwned)
objectLock.lock();

mObject.doSomeModification();

// restore previous lock state
if(!wasObjectLockOwned)
objectLock.unlock();

}

谢谢!

最佳答案

有几种方法可以避免这种编程错误。我建议在类设计级别上进行:

  • 公共(public)私有(private)成员函数分开,
  • 只有 public 成员函数锁定 mutex
  • public成员函数永远不会被其他成员函数调用。

如果一个函数在内部和外部都需要,则创建该函数的两个变体,并将其中一个委托(delegate)给另一个:

public:
// intended to be used from the outside
int foobar(int x, int y)
{
std::unique_lock<std::mutex> lock(mControllerThreadAlive);
return _foobar(x, y);
}
private:
// intended to be used from other (public or private) member functions
int _foobar(int x, int y)
{
// ... code that requires locking
}

关于c++ - 确保线程不会两次锁定互斥体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23234028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com