C/C++中分离(detach)线程的陷阱

C/C++中分离(detach)线程的陷阱

  • 版权声明
  • 线程资源回收
  • pthread_join()
  • pthread_detach()
  • 什么时候分离线程会存在陷阱?
  • 方法论
  • 既使用quick_exit(),又需要析构
  • PS

版权声明

本文为博主原创文章,未经博主允许不得转载。

线程资源回收

线程资源的回收有两种方式:

  1. 连接线程 —— int pthread_join(pthread_t thread, void **retval);
  2. 分离线程 —— int pthread_detach(pthread_t thread);

pthread_join()

  1. 调用pthread_join()会使得当前线程阻塞等待
  2. 当目标线程退出函数会立即返回,然后线程资源回收
  3. 目标函数必须是joinable的(线程创建后默认就是joinable)
  4. 如果retval不是空指针,那么会在retval返回目标线程退出状态
  5. 如果当前线程在等待过程被杀死,那么目标线程还是继续joinable
  6. 请勿多个线程同时join一个目标线程

pthread_detach()

  1. pthread_detach将一条线程由joinable转换成detached
  2. 分离线程的好处是线程退出后,省略了join的步骤,自己回收资源
  3. 已经处于detached的线程切勿再次detached

什么时候分离线程会存在陷阱?

  1. 一个分离线程使用一个共享资源
  2. 分离线程的生命周期比所使用的资源的生命周期

那么就有可能造成未知的错误。

例如:

子线程使用一个全局对象(object),子线程与程序一并退出。

由于程序退出的顺序是:

  1. 对象析构
  2. 子线程退出
  3. 主线程退出

因此,程序退出过程中,全局对象会调用自己的析构函数,此时,对象生命周期结束,对象被销毁。但是,子线程还没马上死亡,子线程仍然有可能继续调用已经析构的对象。期望的结果是安全退出程序,结果却造成了未知的错误。

方法论

  1. 不要使用分离线程
  2. 分离线程不要使用共享资源
  3. 主线程退出前主动销毁子线程(主线程是主动的)
  4. 使用条件变量,主线程等待子线程退出(主线程是被动的)
  5. 使用 void quick_exit (int status) 函数,直接退出,不调用析构函数

既使用quick_exit(),又需要析构

使用 int at_quick_exit( void (*func)(void) ) 函数,注册退出函数。

PS

quick_exit()系列函数包含在中,但Windows不一定(具体和编译器、编译器版本都有关)。

你可能感兴趣的:(C/C++)