一本书讲透Java线程:原理与实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.4.3 线程终止

Linux提供了3种终止线程的方式:第一种是在任务的start函数里执行return语句并返回指定值;第二种是在子线程里调用pthread_exit函数,主动退出;第三种是在主线程里调用pthread_cancel函数来结束子线程。

pthread_exit函数如代码清单1-6所示。

代码清单1-6 pthread_exit函数

参数retval是void*类型的指针,可以指向任何类型的数据,它指向的数据将作为线程退出的返回值,一般用retval来表示线程异常退出的原因。如果线程不需要返回任何数据,可以将retval参数设置为NULL。

代码清单1-7是一个等待线程结束(线程主动退出)的简单示例。exitTask线程函数先打印了一行线程运行状态,然后调用pthread_exit函数来主动退出当前线程,并标明退出的原因是pthread_exit。接下来在main函数中通过pthread_create函数来创建子线程,然后通过pthread_join函数来等待子线程结束。

代码清单1-7 等待线程结束示例

然后通过thread_result来接收并打印子线程的退出原因。pthread_join执行结果如代码清单1-8所示。

代码清单1-8 pthread_join执行结果

调用pthread_cancel函数后并不会让子线程立即终止,只是提出线程取消的请求,pthread_cancel函数定义如代码清单1-9所示。子线程在取消请求(pthread_cancel)发出后会继续运行,直到到达某个取消点(Cancellation Point)。取消点是检查线程是否被取消并按照请求进行动作的位置。

代码清单1-9 pthread_cancel函数定义

pthread_cancel函数会向目标线程发送Cancel信号,但具体如何处理Cancel信号则由目标线程自己决定,目标线程可以选择忽略、立即终止,或者继续运行至取消点。默认情况下,Cancel信号是继续运行至取消点才会退出。

代码清单1-10是一个取消线程的简单示例。cancelTask线程函数先打印了一行线程运行状态,然后调用sleep函数来创造一个线程取消点。在main函数中通过pthread_create创建了子线程,然后通过pthread_cancel函数向子线程发送退出信号。

代码清单1-10 取消线程示例

子线程收到取消信号后,在下一个线程取消点上退出。代码运行结果如代码清单1-11所示。

代码清单1-11 线程取消结果