6个月前 (03-21)  Python |   抢沙发  196 
文章评分 0 次,平均分 0.0
导语:python多进程编程中,一般通过标准库multiprocessing实现,对此,既可以通过Process类实现,也可以通过进程池Pool实现。本文解决的问题是针对Pool的,因为只有在使用进程池时才会出现ctrl c无法正常退出程序,而使用Process类实现时ctrl c可以中止程序并退出。



python多进程编程中,一般通过标准库multiprocessing实现,对此,既可以通过Process类实现,也可以通过进程池Pool实现。本文解决的问题是针对Pool的,因为只有在使用进程池时才会出现ctrl c无法正常退出程序,而使用Process类实现时ctrl c可以中止程序并退出。

在python的多进程编程中,有时候当程序正在执行的时候,我们希望通过ctrl c直接中止程序的执行并正常退出程序,但是在使用Pool的时候,是无法直接退出的。实际上ctrl c之后,子进程接收到这个信号,会中止运行,但是主进程会被阻塞,无法正常退出,具体原因可能是主进程需要等到所有子进程的返回正常运行结果后才会继续执行主进程中的逻辑,但是若子进程是被中断的,则主进程便无法接收到子进程的运行结果,从而会一直阻塞,而且主进程阻塞时也不会接收到ctrl c的中断信号,这样就会导致程序一直卡住,从而无法退出,除非强制杀掉主进程。

这里的‘子进程返回正常的运行结果’实际上就是需要程序正常的运行结束,而不能被中断,但是这其实是算一个python多进程编程的Pool中的一个小bug,因为就算被中断,也应该返回一个结果给主进程,而不是让主进程一直被阻塞。要解决这个问题,实际上我们只要在子进程的执行语句中,加入一个异常捕捉就好。因为ctrl c实际上会给程序抛出一个KeyboardInterrupt异常,所以我们只需要在目标函数的代码中加入try...except KeyboardInterrupt...即可,这样当我们ctrl c的时候,子进程会捕捉到这个异常,然后会正常的退出并把结果传给主进程,从而不会让主进程一直阻塞。

但是要让主进程正常退出,在Unix系统下,其实只要在目标函数的代码中加入KeyboardInterrupt的异常捕捉就够了,这样主进程接收到所有子进程的结果后,会进一步执行下面的语句,然后退出;但是在Windows系统下,这样还是不够的,主进程会进一步执行接下来的语句,但是执行完后并不会正常退出,至于具体原因笔者还不是特别的清楚,希望清楚的读者可以给笔者留言。

所以在Windows系统下,仅仅加入异常捕捉是不够的,还需要在主进程的代码中实现强制杀死主进程的语句,这个可以通过os.popen函数实现,命令为os.popen('taskkill.exe /f /pid:%d'%pid),其中/f表示强制杀死后面的进程id。具体代码如下。

 

————————————————
版权声明:本文为CSDN博主「S_o_l_o_n」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/S_o_l_o_n/article/details/102173303

  转自https://blog.csdn.net/S_o_l_o_n/article/details/102173303
关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册

扫一扫二维码分享