跳转至

shared_ptr

多线程安全性

std::shared_ptr本身是多线程安全的

  • shared_ptr内部的引用计数是std::atomic类型,atomic是一个原子类型,可以在多个线程之间进行安全的并发访问,而不需要任何显式的同步机制
  • atomic类型是在软件层面实现的,但通常会利用 硬件提供的原子指令 来实现高效的原子操作。这些硬件指令允许原子操作 在一个时钟周期内完成 ,而不需要使用锁或其他显式的同步机制

但内部管理的共享对象不是

  • 若对共享对象只读,而不修改,则是线程安全的
  • 若要修改,需要额外的同步操作,以确保线程安全

使用时的注意事项

在非多线程环境中,使用std::shared_ptr需要注意

  1. std::shared_ptr性能开销相对大,避免过度使用
    1. shared_ptr需要维护引用技术和使用原子操作进行同步,因此相对于其他智能指针是重量级
    2. 因此,要根据应用场景灵活使用智能指针。需要高性能的情况下,可考虑传递指针的所有权、或使用其他智能指针(如std::unique_ptr
  2. 避免循环引用。若评估程序存在循环引用的可能,请使用std::weak_ptr来打破循环引用
  3. 不要将std::shared_ptr与裸指针混合使用
    1. 如果混合使用,可能会导致共享指针对象引用计数错误,从而导致内存泄漏或释放了已释放的内存
    2. 在多线程环境下更容易出现这个问题,因此要避免在不同线程之间传递裸指针

在多线程环境中,除了以上内容,还需要注意:

  1. 确保共享对象是线程安全的
    1. 共享对象并不是线程安全的,若涉及到修改操作,就需要进行额外的同步来确保线程安全
  2. 若使用了自定义删除器,请确保它是线程安全的