shared_ptr
多线程安全性¶
std::shared_ptr
本身是多线程安全的
shared_ptr
内部的引用计数是std::atomic
类型,atomic
是一个原子类型,可以在多个线程之间进行安全的并发访问,而不需要任何显式的同步机制atomic
类型是在软件层面实现的,但通常会利用 硬件提供的原子指令 来实现高效的原子操作。这些硬件指令允许原子操作 在一个时钟周期内完成 ,而不需要使用锁或其他显式的同步机制
但内部管理的共享对象不是
- 若对共享对象只读,而不修改,则是线程安全的
- 若要修改,需要额外的同步操作,以确保线程安全
使用时的注意事项¶
在非多线程环境中,使用std::shared_ptr
需要注意
std::shared_ptr
性能开销相对大,避免过度使用shared_ptr
需要维护引用技术和使用原子操作进行同步,因此相对于其他智能指针是重量级- 因此,要根据应用场景灵活使用智能指针。需要高性能的情况下,可考虑传递指针的所有权、或使用其他智能指针(如
std::unique_ptr
)
- 避免循环引用。若评估程序存在循环引用的可能,请使用
std::weak_ptr
来打破循环引用 - 不要将
std::shared_ptr
与裸指针混合使用- 如果混合使用,可能会导致共享指针对象引用计数错误,从而导致内存泄漏或释放了已释放的内存
- 在多线程环境下更容易出现这个问题,因此要避免在不同线程之间传递裸指针
在多线程环境中,除了以上内容,还需要注意:
- 确保共享对象是线程安全的
- 共享对象并不是线程安全的,若涉及到修改操作,就需要进行额外的同步来确保线程安全
- 若使用了自定义删除器,请确保它是线程安全的