【问题标题】:How to terminate a python process and enter the finally block in python try-except statement?如何终止python进程并在python try-except语句中输入finally块?
【发布时间】:2022-01-24 09:57:32
【问题描述】:

我有两个 python 文件:script.pycounting.py

counting.py

from time import sleep

try:
    for n in range(1, 10):
        print('counting', n)
        sleep(1)
except Exception as e:
    print('program terminated with exception', e)
else:
    print('program ended')
finally:
    sleep(4)
    print('this is the finally block')

script.py

import sys
import pathlib
import subprocess
import signal


on_windows = True if sys.platform == 'win32' else False
on_linux = True if sys.platform == 'linux' else False

if on_windows:
    process = subprocess.Popen(
        ['python', 'counting.py'],
        cwd=pathlib.Path(__file__).parent.resolve(),
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        universal_newlines=True,
        creationflags=subprocess.CREATE_NEW_PROCESS_GROUP,
    )
elif on_linux:
    process = subprocess.Popen(
        ['python', 'counting.py'],
        cwd=pathlib.Path(__file__).parent.resolve(),
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        universal_newlines=True,
        preexec_fn=os.setsid,
    )
try:
    out, err = process.communicate(timeout=4)
    print(out, err)
except subprocess.TimeoutExpired:
    if on_windows:
        process.send_signal(signal.CTRL_BREAK_EVENT)
        process.kill()
    elif on_linux:
        os.killpg(process.pid, signal.SIGTERM)
    print('time out')

当我运行script.py 时,输出是:

time out

Process returned 0 (0x0)        execution time : 4.778 s

如何终止process,并在counting.py 文件中输入finally 块?

附注 当我在终端中运行counting.py 时,程序在键盘上的CTRL+C 之后进入finally 块:

>>python counting.py
counting 1
counting 2
counting 3
this is the finally block
Traceback (most recent call last):
  File "counting.py", line 6, in <module>
    sleep(1)
KeyboardInterrupt
^C
>>

如何使用subprocess 模块并杀死子进程来实现这一点? 以上代码我已经在Windows(Windows 10)和Linux(CentOS 8)中测试过了。

【问题讨论】:

  • 我不知道它是否有帮助,但break 关键字会停止你的循环。只需在空行中输入即可。
  • True if x else False 只是 bool(x)(它本身有时只是 x)。

标签: python operating-system try-catch terminate


【解决方案1】:

首先,counting.py 不会打印任何东西,除非你让它向标准输出发出一些东西:

process = subprocess.Popen(
    ['python', 'counting.py'],
    cwd=pathlib.Path(__file__).parent.resolve(),
    stdout=None,
    stderr=None,
    universal_newlines=True,
    preexec_fn=os.setsid,
)

其次,你script.py中的异常处理程序没有被调用,因为它不是超时异常,所以改为:

try:
    out, err = process.communicate(timeout=4)
    print(out, err)
except:

第三,至少在 Linux 上,os.killpg() 将终止进程而不是中断它,因此不会调用counting.py 中的异常处理程序。代替SIGTERM,使用:

elif on_linux:
    os.killpg(process.pid, signal.SIGINT)

通过这 2 个更改:

$ ./script.py 
counting 1
counting 2
time out
$ this is the finally block
Traceback (most recent call last):
  File "counting.py", line 8, in <module>
    sleep(1)
KeyboardInterrupt

【讨论】:

    猜你喜欢
    • 2018-03-19
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 2011-04-08
    相关资源
    最近更新 更多