LeC*_*Coc 5 c++ qt multithreading
具体来说,在 const 成员函数中,如果我mutex.lock()在它的开头和mutex.unlock()返回之前使用,在 OpenMP 循环中运行它时会崩溃。但是如果我QMutexLocker(&mutex)在函数的开头用一个替换这两个调用,它运行起来很顺利。Visual Studio 2010,Qt 4.8。我希望这两个代码是等价的,但显然不是。我在这里缺少什么?
编辑:虽然这不会重现问题,但一个小例子:
class TileCache
{
public:
bool fillBuffer(const std::string& name) const {
//QMutexLocker lock(&mCacheMutex);
mCacheMutex.lock();
auto ite = mCache.find(name);
if(ite == mCache.end())
mCache.insert(ite, std::make_pair(name, new unsigned char[1024]));
// code here
mCacheMutex.unlock();
return true;
}
private:
mutable std::map<std::string, unsigned char*> mCache;
mutable QMutex mCacheMutex;
};
int main(int argc, char *argv[])
{
std::cout << "Test" << std::endl;
TileCache cache;
#pragma omp parallel for shared(cache)
for(int i = 0; i < 2048; ++i)
{
cache.fillBuffer("my buffer");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我基本上是在问是否有任何已知的理由相信这两种方式是不等价的,如果总是调用lock()/ unlock()(没有lock()匹配的调用unlock())QMutexLocker在某些情况下的行为与,不同。
Locker 对象的优点是自动处理所有退出点,包括由异常引起的退出点。
通常,忘记退出点或异常只会使互斥体锁定,症状是程序挂起。
如果您遇到崩溃,那么问题出在其他地方,并且您在使用储物柜对象时看到问题消失的事实只是巧合(如果发生崩溃,则程序肯定有错误,如果没有崩溃,则不能说程序是正确的......尤其是在像 C++ 这样的语言中,有“未定义行为”的概念)。
另一个不明显的优点是,使用作为第一个语句创建的锁对象,可以保证解锁将作为返回调用者之前的最后一件事发生。如果函数内部创建了依赖于互斥体的其他对象,这可能会产生影响:
void ok_func() {
Locker mylock(mymutex);
Obj myobj; // constructor and destructor require the lock
}
void buggy_func() {
lock(mymutex);
Obj myobj; // constructor and destructor require the lock
unlock(mymutex);
// Bug: myobj instance will be destroyed without the lock
}
void workaround_func() {
lock(mymutex);
{ // nested scope needed
Obj myobj; // constructor and destructor require the lock
}
unlock(mymutex);
}
Run Code Online (Sandbox Code Playgroud)