在容器中存储指向对象的指针时的线程安全
Thread safety when storing pointers to object in container
我有一个关于需要实现互斥锁时的良好代码实践的问题。请考虑下面的代码示例,其中有一个管理器类 (Group(,它保存指向对象 (Person( 的指针容器。
如果 Group 类由多个线程共享,那么访问 Person 对象的公共方法的正确方法是什么?
因为当我执行"getPerson(("时,我会检索指针。但是当我尝试执行"getName(("时,可能已经删除/删除了 person 对象。这是如何以好的方式完成的?
编辑:此示例不是多线程的,但请考虑在多线程环境中使用的此类:)
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();
}
当我执行"getPerson(("时,我检索指针。但是当我尝试执行"getName(("时,可能已经删除/删除了 person 对象。
"已删除"部分听起来像是std::shared_ptr
(https://en.cppreference.com/w/cpp/memory/shared_ptr(的一个很好的用例
如果在任何地方都使用共享指针,则永远不会显式删除对象:允许 shared_ptr
类在销毁或重新分配最后一个引用时(且仅在(自动删除它。
这并不能解决一个线程通过特定组中的成员身份获取对某人的引用,而另一个线程同时从同一组中删除同一个人意味着什么的问题。这是一个更高级别的争用条件,您可能只能通过实现一些适当的高级和特定于应用程序的策略来防止或应对。
相关文章:
- 如何检索指向在单独线程上运行的函数的移动指针?
- 如何将'this'指针传递给C++ WinAPI 线程?
- 从子线程访问指针
- 将字符串指针传递到C++和Xcode 11.1中不同线程上运行的函数
- 通过std::shared_ptr使用Rcpp和RcppParallel的线程安全函数指针
- 在多线程函数中返回共享的常量指针会导致计时问题吗?
- 线程中的成员函数指针
- 如何安全地终止线程?(使用指针)C++
- 指向成员对象的指针 - 中断线程
- 是否可以访问非线程安全容器内指针指向的值(线程安全映射中的条目)?
- 如何抓取指向Qt中弹出对话框的指针,该对话框阻止了QTest中的UI线程
- 将指针传递到另一个线程的正确方法
- CPP:如何使用需要指针的方法创建线程
- 启动线程会导致指针初始化时出现分段错误
- 是否访问指针元组和互斥锁线程安全
- 在容器中存储指向对象的指针时的线程安全
- 为什么当我在构造函数中创建线程时,实例化对象和对象的指针的行为不同
- 指针在不同的线程中获得错误的价值
- C++ 线程函数指针实现返回错误无效使用非静态成员函数
- 指向对象初始化的静态指针——线程安全