[Python]进程—函数堵塞的解决方法
[Python]进程—函数堵塞的解决方法
前言
最近一直没有更新文档站,因为一直在开发python的一个小项目。
在开发的过程中也遇到了许多问题,比如在开发的方法选择上就出现了比较大的问题,这个以后可能有时间会写出来分享一下。
今天这个问题就是我在开发这个项目时遇到的。
问题
这个函数是一个图像识别进行操作的函数,因为是基于图像识别的可能就会出现死循环的情况,而函数内部又没有进行处理。
导致我在主函数调用时也会出现死循环。
思考过程
因为之前没有遇到过这种情况,所以一开始也没有什么思路,只能先去网上找找看有没有什么关于超时处理的解决方案。
网上有说使用signal的,但是我看了下貌似不适用于windows系统。
还有的是用其他人的包,但是我看了下作者的github,貌似已经很久没更新了,并且有issue说py3.12存在问题。
因此我就放弃了这两种做法。
于是询问AI,AI提供了两种思路线程(thread) 和 进程(process)。
线程和进程
线程(thread)
线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
上面是网上对线程的解释,可以线程的看出的开销是比进程小的。
但是它有一个致命的问题,它不能被强制终止,对于我子函数本身存在死循环的情况下是不适用的。
进程(process)
进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
进程虽然相对线程来说开销较大,但因为我这个项目并不算大,目前也并不存在多进程的情况,性能上不会造成什么大的影响。\
最重要的是它能够在运行时被终止,这就是我所需要的。
解决方法——进程
既然已经确定了它需要用进程解决,那我们就来看下进程如何使用吧
进程的创建
在python中,进程的创建需要使用multiprocessing模块,这个模块提供了Process类来创建进程。
import multiprocessing
# 创建进程 target是进程要执行的函数,args是函数的参数
p = multiprocessing.Process(target=func, args=(arg1, arg2))
进程的启动
创建完进程后,需要调用start()方法来启动进程。
p.start()
进程的阻塞
然后调用join()方法来阻塞主进程,直到子进程执行完毕。
join()方法还有一个可选参数timeout,用于设置阻塞的时间,如果子进程在timeout时间内没有执行完毕,主进程会继续执行。
sec = 10
p.join(timeout=sec)
进程的终止以及判断进程存活
如果子进程在timeout时间内没有执行完毕,主进程会继续执行,但是子进程还在运行,这时候就需要终止子进程了。
但在终止前我们可以进行下判断,判断进程是否存活(可选)
if p.is_alive(): # 判断进程是否存活
print("进程仍在运行,强制结束进程")
p.terminate()
else:
print("进程已结束")
完整案例
下面是我根据我的项目写出的进程函数,需要使用时可以参考一下
def create_process(func,args,f_sec,f_name):
p = multiprocessing.Process(target=func, args=args)
p.start()
p.join(timeout=f_sec)
if p.is_alive():
print(f"{f_name}执行超时")
p.terminate()
else:
print("未超时")