当前位置: 主页 > Python语言

python 多线程进度条-python 全局 线程

发布时间:2023-02-10 10:33   浏览次数:次   作者:佚名

前言:

今天给大家带来的是Python:用Ctrl+C解决多线程程序终止问题! 文章中的代码具有很好的参考价值,希望对您有所帮助! (大部分代码以图片形式呈现,方便大家观看收藏)

出发点:

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

代码如下:

python 多线程进度条_python 全局 线程_python 线程池模块

python 多线程进度条_python 线程池模块_python 全局 线程

python 线程池模块_python 全局 线程_python 多线程进度条

这里提醒一下:以上是一个模拟程序,并没有真正向服务发送请求。

相反,在 1000 万以内,每个线程每并发数 (cc) 打印一个整数。 显然,当所有线程都完成任务后,进程就会优雅地退出。 但是如果我们想中途退出(想象一个压力测试程序,我们中途发现问题需要停止测试),怎么办?

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

但实际上这个程序是行不通的,当你按下Ctrl+C时python 多线程进度条,程序照常运行,没有任何反应。 在网上查了一些资料,了解到如果python的子线程不是daemon,主线程是无法响应任何中断的。 但是设置为daemon后,主线程会退出,然后整个进程很快就会退出,所以需要在主线程中检测各个子线程的状态,直到所有子线程都退出才会退出线程退出python 多线程进度条,所以上面例子中的第29行 之后的代码可以修改为:

python 全局 线程_python 多线程进度条_python 线程池模块

代码如下:

python 线程池模块_python 全局 线程_python 多线程进度条

再试一次,问题还是没有解决,进程仍然没有响应Ctrl+C,这是因为join()函数也会等待锁,导致主线程抓不到信号。 于是继续修改,调用线程的isAlive()函数判断线程是否完成:

代码如下:

while 1:

python 全局 线程_python 线程池模块_python 多线程进度条

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

python 全局 线程_python 线程池模块_python 多线程进度条

注意:这样修改后,程序运行完全符合预期:可以顺利打印出每个线程应该打印的所有数字,也可以使用Ctrl+C中途终止整个过程。

完整代码如下:

python 多线程进度条_python 线程池模块_python 全局 线程

提示:图1、2、3的代码都放在一起了!

python 线程池模块_python 多线程进度条_python 全局 线程

python 线程池模块_python 全局 线程_python 多线程进度条

python 线程池模块_python 全局 线程_python 多线程进度条

其实如果你用python写一个服务,你需要这样做,因为负责服务的线程一直在那里接收请求,不会退出,如果你想用Ctrl+C杀掉整个服务,按照上面的压力测试方案是有道理的。 综上所述,在python多线程中响应Ctrl+C信号杀掉整个进程,需要:

1.将所有子线程设置为Daemon;

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

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