我有一个存储在多线程应用程序中的资源存储对象。为了(希望)确保线程安全我每次想要访问资源或插入新资源时都会锁定互斥锁。例如,要插入新资源:
void ResourceManager::insertResource(const std::string& id)
{
// create the object with such ID
Resource res = Resource(id);
// ... more code on res
// lock the mutex to insert the resource
std::lock_guard<std::mutex> guard(mResourcesMutex);
// insert the resource in a STL container
mResources.insert(ResourceContainer::value_type(id, res));
// ... more code that does not require the mutex lock
}
我希望lock_guard最小化范围,以便尽快调用析构函数,其他线程可以访问资源。特别是,我想在mResources.insert(...)语句之后解锁互斥锁。
我想过使用一个天真的if语句来确定lock_guard的范围:
if(true)
{
std::lock_guard<std::mutex> guard(mResourceMutex);
mResources.insert(ResourceContainer::value_type(id, res);
}
但我不知道它的工作原理。我发现很难检查这是否确定了lock_guard是否正确,或者另一方面,编译器是否认为我疯了并且优化代码取出if语句。
我的问题是:
答案 0 :(得分:6)
是的,它有效。退出作用域后,该作用域的本地对象将立即销毁。
是的,这是值得的,特别是在你的例子(减少对象的生命周期以确保资源早期发布)的情况下 - 但你也可以使用它只是为了减少临时标识符的范围和在此之后使它无法访问,即使这个用法比你的例子更有趣。)
是的,有一个(稍微)更好的选择:只使用没有if
子句的大括号:
{
std::lock_guard<std::mutex> guard(mResourceMutex);
mResources.insert(ResourceContainer::value_type(id, res);
}
正确的编译器将能够优化if (true)
,因此生成的代码将是相同的,但从样式的角度来看,单独的大括号更清晰。此外,单独的大括号是一个众所周知且立即可识别的习语,而你的if (true)
不是,并且让读者想知道(即使是短暂的)“如果是这样的目的是什么?哦,等等,对,这是通常的范围限制习语...... “。
答案 1 :(得分:5)
为什么使用if(true)
?
您只需使用block scope
{
std::lock_guard<std::mutex> guard(mResourceMutex);
mResources.insert(ResourceContainer::value_type(id, res);
}