【发布时间】:2014-04-23 18:01:28
【问题描述】:
我有一个类,其中包含指向该类所有实例的静态指针向量。当我通过静态 getter 方法访问成员变量时,有时会得到错误的结果。
代码:
hpp 文件:
class ObjectID {
public:
ObjectID();
float getShininess() const { return m_shininess; }
static const std::shared_ptr<ObjectID> getID(unsigned long);
private:
float m_shininess;
static std::vector<std::shared_ptr<ObjectID>> s_ids;
}
cpp 文件:
static std::mutex s_mutex;
std::vector<std::shared_ptr<ObjectID>> ObjectID::s_ids = {};
const std::shared_ptr<ObjectID> ObjectID::getID(unsigned long id) {
std::lock_guard<std::mutex> lock(s_mutex);
std::shared_ptr<ObjectID> ptr = s_ids.at(id - 1);
return ptr;
}
ObjectID::ObjectID()
: m_shininess(50.f)
{
std::lock_guard<std::mutex> lock(s_mutex);
s_ids.emplace_back(this);
}
我怀疑这与我使用两个线程的事实有关。但是添加互斥锁并没有改变任何东西。
为了澄清,一个线程创建 ObjectID,另一个线程调用
ObjectID::getID(id)->getShininess();
我并不总是得到 50,有时我得到 1,而且我从不改变 m_shininess。 有什么想法吗?
编辑:
ObjectID 是在另一个类中创建的,该类具有 ObjectID 的向量。
m_objects.emplace_back();
【问题讨论】:
-
你怎么知道哪些 id 是有效的?
-
你怎么知道
s_ids.emplace_back(this);中的this甚至是动态分配的? -
@nosid:在 cpp 文件中,我将其添加到代码中。
-
@WhozCraig -- 确切地说,如果 ObjectID 是在堆栈上创建的,或者它是在构造函数外部创建并绑定到 shared_ptr 的,这可能会失败。
-
@gartenriese 类似于我可能会这样做,特别是隐藏构造函数。如果这是多线程的,你仍然需要在修改和查询期间保护
s_ids,但模型是健全的。
标签: c++ multithreading static