龙空技术网

Python:用Ctrl+C解决终止多线程程序的问题!(建议收藏)

程序员陈平安 377

前言:

现在各位老铁们对“python脚本退出”都比较看重,你们都想要剖析一些“python脚本退出”的相关知识。那么小编也在网络上搜集了一些关于“python脚本退出””的相关资讯,希望小伙伴们能喜欢,小伙伴们快快来了解一下吧!

前言:

今天为大家带来的内容是Python:用Ctrl+C解决终止多线程程序的问题!文章中的代码具有不错的参考意义,希望在此能够帮助到各位!(多数代码用图片的方式呈现出来,方便各位观看与收藏)

出发点:

前段时间,花了一天时间用python为服务写了个压力测试。很简单,多线程向服务器发请求。但写完之后发现如果中途想停下来,按Ctrl+C达不到效果,自然想到要用信号处理函数捕捉信号,使线程都停下来,问题解决的方法请往下看:

代码如下:

在这里提示一句:上面是一个模拟程序,并不真正向服务发送请求。

而代之以在一千万以内,每个线程每隔并发数个(cc个)打印一个整数。很明显,当所有线程都完成自己的任务后,进程会正常退出。但如果我们中途想退出(试想一个压力测试程序,在中途已经发现了问题,需要停止测试),该肿么办?

你当然可以用ps查找到进程号,然后kill -9杀掉,但这样太繁琐了,捕捉Ctrl+C是最自然的想法。上面示例程序中已经捕捉了这个信号,并修改全局变量is_exit,线程中会检测这个变量,及时退出。

但事实上这个程序并不work,当你按下Ctrl+C时,程序照常运行,并无任何响应。网上搜了一些资料,明白是python的子线程如果不是daemon的话,主线程是不能响应任何中断的。但设为daemon后主线程会随之退出,接着整个进程很快就退出了,所以还需要在主线程中检测各个子线程的状态,直到所有子线程退出后自己才退出,因此上例29行之后的代码可以修改为:

代码如下:

重新试一下,问题依然没有解决,进程还是没有响应Ctrl+C,这是因为join()函数同样会waiting在一个锁上,使主线程无法捕获信号。因此继续修改,调用线程的isAlive()函数判断线程是否完成:

代码如下:

while 1: alive = False for i in range(cc): alive = alive or threads[i].isAlive() if not alive: break

注意:这样修改后,程序完全按照预想运行了:可以顺利的打印每个线程应该打印的所有数字,也可以中途用Ctrl+C终结整个进程。

完整的代码如下:

提示:图一,二,三中的代码都是一起的!

其实,如果用python写一个服务,也需要这样,因为负责服务的那个线程是永远在那里接收请求的,不会退出,而如果你想用Ctrl+C杀死整个服务,跟上面的压力测试程序是一个道理。总结一下,python多线程中要响应Ctrl+C的信号以杀死整个进程,需要:

1.把所有子线程设为Daemon;

2.使用isAlive()函数判断所有子线程是否完成,而不是在主线程中用join()函数等待完成;

3.写一个响应Ctrl+C信号的函数,修改全局变量,使得各子线程能够检测到,并正常退出。

以上就是本文的全部内容啦!

小编在这里说句:我是一名python开发工程师,最近翻了以前的笔记,总结了工作这么久的经验,共整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习,面试宝典,面试宝典,面试宝典。想要这些资料的可以关注小编,并在后台私信小编:“07”即可领取

标签: #python脚本退出 #python多线程join之后一直不结束 #python多线程异常处理 #python线程重启 #python的线程怎么结束