簡體   English   中英

如何終止 python 進程並在 python try-except 語句中輸入 finally 塊?

[英]How to terminate a python process and enter the finally block in python try-except statement?

我有兩個 python 文件: script.pycounting.py

計數.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')

腳本.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時,output 是:

time out

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

如何終止process ,並在counting.py文件中輸入finally塊?

PS當我在終端中運行counting.py時,程序進入finally塊,在鍵盤上按CTRL+C后:

>>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) 中測試了上述代碼。

首先, 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)

有了這兩個變化:

$ ./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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM