满足指定条件时终止目标pthread线程的方法及API选择
选型结论
直接说结论:pthread_exit()和pthread_join()的组合从根上就实现不了你要的跨线程终止pt3的需求;pthread_cancel()和pthread_testcancel()虽然能实现,但坑不少,工程上更推荐用协作式标志位的方案,比这俩组合都靠谱。
两组API的实际作用和局限
- 别搞混
pthread_exit()的作用域:哪个线程调用这个函数,哪个线程自己就会退出。你在pt2里写pthread_exit(),退的是pt2本身,半分影响不到pt3的执行流。而pthread_join()只是个资源回收函数,它会阻塞等着目标线程自己跑完,把退出线程的栈、线程描述符这类资源收回来,本身没有任何强制终止运行中线程的能力,这俩凑一起根本达不到你要的效果。 pthread_cancel()确实是用来给其他线程发终止请求的,默认是延迟取消模式:目标线程收到请求不会立刻退出,只有跑到系统定义的取消点(比如read、sleep这类阻塞式系统调用),或者你手动在代码里插的pthread_testcancel()位置时,才会真正退出。这组搭配确实能实现你要的逻辑,但风险很高:如果pt3被取消的时候正持有互斥锁、申请了堆内存没free、打开了文件没关,这些资源不会自动清理,很容易搞出死锁、内存泄漏、文件句柄泄漏这类排查成本极高的问题。
推荐的稳妥实现
别上来就想着强制杀线程,POSIX线程模型下最安全的做法是协作式退出,实现起来也很简单:
- 定义一个原子变量,或者加互斥锁保护的布尔值,作为pt3的退出标记
- pt2检测到全局变量到100的触发条件时,把这个退出标记设为真
- 在pt3的业务逻辑里,每执行完一小段流程就主动查一次这个标记,一旦发现要退出,先把自己持有的锁、申请的堆内存、打开的文件全释放干净,再自己调用
pthread_exit(NULL)退出 - 后续在合适的位置(比如主线程或者pt1的逻辑里)调用
pthread_join(pt3, NULL)把pt3的剩余资源回收完就完事,不会留任何隐患。
要是你的pt3逻辑特别简单,全程没有需要手动释放的资源,那直接用
pthread_cancel()+pthread_testcancel()快速实现也不是不行,记得把pthread_testcancel()插在pt3没持有任何资源的安全位置就好。
内容的提问来源于stack exchange,提问作者albert
相关产品推荐
相关产品推荐

