当需要实现互斥时,我有一个关于良好代码实践的问题。考虑下面的代码示例,其中有一个管理器类(组),其中包含一个指向对象(人)的指针的容器。
如果Group类由多个线程共享,那么访问Person对象的公共方法的正确方法是什么?
因为当我执行'getPerson()'时,我检索了指针。但是,当我尝试执行'getName()'时,有可能已删除/删除了人员对象。如何做到这一点的好方法?
编辑:此示例不是多线程的,但请考虑在多线程环境中使用的此类:)
class Person
{
public:
Person(std::string name, std::string place) :
m_name(name),
m_place(place) {};
~Person() {};
std::string getName(){return m_name;}
std::string getPlace(){return m_place;}
private:
std::string m_name;
std::string m_place;
};
class Group
{
public:
Group() :
m_persons(100) {};
~Group(){};
void createPerson() {
std::lock_guard<std::mutex> l(m_mtx);
Person* p = new Person("John", "London");
m_persons.push_back(p);
}
void removePerson(int index) {
std::lock_guard<std::mutex> l(m_mtx);
m_persons.erase(m_persons.begin() + index);
}
Person* getPerson(int index) {
std::lock_guard<std::mutex> l(m_mtx);
return m_persons[index];
}
private:
std::vector<Person*> m_persons;
std::mutex m_mtx;
};
int main() {
Group g();
g.createPerson();
g.createPerson();
std::cout << g.getPerson(0).getName();
}
答案 0 :(得分:0)
当我执行'getPerson()'时,我检索了指针。但是,当我尝试执行'getName()'时,有可能已删除/删除了人员对象。
“已删除”部分听起来像是std::shared_ptr
(https://en.cppreference.com/w/cpp/memory/shared_ptr)的一个好用例
如果在各处使用共享指针,则永远不会显式删除对象:您允许shared_ptr
类在(且仅在)最后一个引用被破坏或重新分配时自动删除它。
这不能解决以下问题:一个线程通过其在特定组中的成员身份获得对某人的引用,而另一个线程同时将该人从同一组中删除。这是一个更高级别的竞争条件,您可能只能通过实施一些适当的高层且 application-specific 策略来预防或应对。