我正在做一个单身设计模式的练习。从讨论here和here,我明白本地静态变量的初始化是自C++ 11以来的线程安全。请考虑下面的代码片段的代码,本地静态变量的单身构造函数
std::shared_ptr<ApiFacade> ApiFacade::GetInstance(const std::string & url)
{
// Initialization of function-local statics is guaranteed to occur only
// once even when called from multiple threads, and may be more efficient
// than the equivalent code using std::call_once.
static std::shared_ptr<ApiFacade> rest = nullptr;
if (rest == nullptr)
{
if (!url.empty())
{
rest = std::shared_ptr<ApiFacade>(new ApiFacade(url));
}
else
{
throw std::invalid_argument("Failed creating REST API object, Pass a valid URL");
}
}
return rest;
}
这里本地的静态与初始化nullptr
第一,然后使用rest = std::shared_ptr<ApiFacade>(new ApiFacade(url));
相应指针分配。我想知道是否确保线程安全,直到本地static
被分配了ApiFacade
的实例,或者我仍然需要在这种情况下使用DCLP。这里的本地static
初始化是用nullptr
完成的,后来用ApiFacade
的一个实例完成。
但是我试图解决如下的比赛条件,但@Etherealone解决方案看起来不错
{
static std::shared_ptr<ApiFacade> rest = nullptr;
if (rest == nullptr)
{
// Mutex to provide exclusive access to resource.
std::recursive_mutex singleTonMtx = {};
std::lock_guard<std::recursive_mutex> lock(singleTonMtx);
if (!url.empty() && (rest == nullptr))
{
rest = std::shared_ptr<ApiFacade>(new ApiFacade(url));
}
else
{
throw std::invalid_argument("Failed creating API object, Pass a valid URL");
}
}
return rest;
}
我投票作为题外话,因为这个问题属于http://codereview.stackexchange.com – user3159253
'静态的std :: shared_ptr的休息=的std :: make_shared (URL)来关闭这个问题;返回休息;'。你的版本不是thread_safe。 –
Jarod42
@ Jarod42,我明白,但我需要在创建'std :: shared_ptr'之前验证'url'。 – Panch