[英]How to terminate a python process and enter the finally block in python try-except statement?
我有兩個 python 文件: script.py
和counting.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.