1. 线程安全的定义

  • 多个线程同时访问,表现出正常的行为
  • 无论这些操作系统如何调度这些线程,无论这些线程的执行顺序如何交织
  • 调用端无需额外的同步或其他协调动作

PS: c++的常用容器都不是线程安全的,如std::vector,std::string、std::map。因为需要额外的锁保证线程安全

2. 对象创建的线程安全

  • 构造期间不泄露this指针

3. 对象销毁的问题

  • 尝试使用mutex,但是mutex不能很好解决多线程销毁

a. 考虑以下代码, 尝试使用mutex保护析构函数

| ```cpp Foo::~Foo() { Lockguard lock(mutex_); // free internal state (1) }

  1. | ```cpp
  2. void Foo::update()
  3. {
  4. Lockguard<mutex> lock(mutex_);
  5. // make use of internal state
  6. }

| | —- | —- |

b. 此时有A,B线程都能使用Foo的对象x,A准备销毁x, B准备调用update()

| ```cpp // thread A delete x; x = nullpter;

  1. | ```cpp
  2. // thread B
  3. if(x)
  4. {
  5. x->update();
  6. }

| | —- | —- |

c. 尽管A将指针置位nullptr, B在调用前检查了x,但是无法避免一种情况。

  1. A运行到(1), 持有互斥锁
  2. B运行到(2), 持有互斥锁,此时A销毁完毕,而B持有的互斥锁被销毁。

接下来发生什么不知道。

  • 结论:作为成员的mutex不能保护析构函数