我有一个代表不同类型工具的类(GCC,LEX,YACC,......)。 每个实例都有一个表示工具的类型,并允许特殊配置。
要处理默认配置,我有一组地图和矢量存储默认值。因为我希望该类在每个上下文中都可用,所以它必须是线程安全的,因此为了避免竞争我实现了以下内容:
int Tool::addType(std::string typeName,
std::string typeFlagName)
throw (GP::Exceptions::LockAcquisitionException)
{
static std::timed_mutex mutex;
std::unique_lock<std::timed_mutex> lock{mutex};
int typeId = 0;
if (lock.try_lock_for(std::chrono::microseconds(100)))
{
int typeId = typeNames.size();
typeNames[typeId] = typeName;
typeFlagNames[typeId] = typeFlagName;
}
else
{
throw GP::Exceptions::LockAcquisitionException{"Unable to generate new type ID within 100 microseconds."};
}
return typeId;
}
我想知道这是一个很好的解决方案还是我错过了什么。 如果这没关系,还有另一种解决方案不那么详细吗?
答案 0 :(得分:4)
为什么不喜欢?
class tool
{
std::atomic<int> index_;
std::array<std::pair<std::string, std::string>, 2048> types_; // Should be more than enough room.
int addType(std::string typeName, std::string typeFlagName)
{
int id = index++;
if(id >= types_.size())
throw GP::Exceptions{"To many types."};
types_[id] = std::make_pair(typeName, typeFlagName);
return id;
}
};
你可以通过使用std :: vector使它变得更聪明,只有在需要重新分配更大的大小时才能锁定。
注意:在C ++ 11中不推荐使用throw()子句。
答案 1 :(得分:3)
我的建议是:
class tool
{
std::mutex myMutex;
std::vector<std::string> typeNames;
int addType(std::string typeName)
{
std::lock_guard myLock(myMutex);
typeNames.push_back(typeName);
return typeNames.size()-1; //
}
// Only hold lock when needed
void longComplexFunction(int f)
{
// Compute as much as possible before
int complexMagic = veryLongFunction(f);
{
std::lock_guard myLock(myMutex);
typeNames[complexMagic] += "s";
}
}
}