前言:
不要试图用强制方法杀掉一个python线程,这从服务设计上就存在不合理性。 多线程本用来任务的协作并发,如果你使用强制手段干掉线程,那么很大几率出现意想不到的bug。 请记住一点,锁资源不会因为线程退出而释放锁资源 !
我们可以举出两个常见的例子:
1. 有个A线程拿到了锁,因为他是被强制干掉的,没能及时的release()释放锁资源,那么导致所有的线程获取资源是都被阻塞下去,这就是典型的死锁场景。
2.在常见的生产消费者的场景下,消费者从任务队列获取任务,但是被干掉后没有把正在做的任务丢回队列中,那么这就造成了数据丢失。
下面是java和python终止线程的方法:
java有三种方法可以使终止线程:
1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
2. 使用stop方法强行终止线程(不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。
3. 使用interrupt方法中断线程。
python可以有两种方法:
1. 退出标记
2. 使用ctypes强行杀掉线程
不管是python还是java环境下,理想的停止退出线程方法是 让线程自个自杀,所谓的线程自杀就是 你给他一个标志位,他退出线程。
下面我们会采用多种方法来测试 停止python线程的异常情况。我们查看一个进程所有的执行线程, 进程是用过掌控资源,线程是用作调度单元,进程要被调度执行必须要有一个线程,默认的线程和进程的pid一样的。
ps -mp 31449 -o THREAD,tid USER %CPU PRI SCNT WCHAN USER SYSTEM TIDroot 0.0 - - - - - -root 0.0 19 - poll_s - - 31449root 0.0 19 - poll_s - - 31450
获取到了进程所有的线程后,通过strace得知 31450 是需要我们kill的线程id,当我们kill的时候,会出现整个进程都崩溃的情况。 在多线程环境下,产生的信号是传递给整个进程的,一般而言,所有线程都有机会收到这个信号,进程在收到信号的的线程上下文执行信号处理函数,具体是哪个线程执行的难以获知。也就是说,信号会随机发个该进程的一个线程。
strace -p <span style="font-size:14px;line-height:21px;">31450</span> Process <span style="font-size:14px;line-height:21px;">31450</span> attached - interrupt to quitselect(0, NULL, NULL, NULL, {0, 320326}) = 0 (Timeout)select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)select(0, NULL, NULL, NULL, {1, 0}) = ? ERESTARTNOHAND (To be restarted)--- SIGTERM (Terminated) @ 0 (0) ---Process <span style="font-size:14px;line-height:21px;">31450</span> detached
新闻热点
疑难解答