Python 无法通过 Ctrl+C 或 Ctrl+Break 终止脚本
Python script can't be terminated through Ctrl+C or Ctrl+Break
我有这个名为 myMain.py
的简单 python 脚本来自动执行另一个 python 程序并增加数字,我在 CentOS 7 上 运行 它:
#!/usr/bin/python
import os
import sys
import time
def main():
step_indicator = ""
arrow = ">"
step = 2
try:
for i in range(0,360, step):
step_percentage = float(i)/360.0 * 100
if i % 10 == 0:
step_indicator += "="
os.system("python myParsePDB.py -i BP1.pdb -c 1 -s %s" % step)
print("step_percentage%s%s%.2f" % (step_indicator,arrow,step_percentage)+"%")
except KeyboardInterrupt:
print("Stop me!")
sys.exit(0)
if __name__ == "__main__":
main()
现在我只知道这个脚本是单线程安全的,但我不能用 Ctrl+C
键盘中断来终止它。
我看了一些相关的问题:比如Cannot kill Python script with Ctrl-C and Stopping python using ctrl+c我意识到Ctrl+Z
不会杀死进程,它只是暂停进程并让进程保持在后台。 Ctrl+Break
也适用于我的情况,我认为它只会终止我的主线程但保留子进程。
我还注意到调用 os.system()
会从当前执行的进程中生成一个子进程。同时,我还有 os
文件 I/O 函数并且 os.system("rm -rf legacy/*")
将在 myParsePDB.py
中调用,这意味着此 myParsePDB.py
子进程将生成子进程作为出色地。然后,如果我想在 myMain.py
中捕获 Ctrl+C
,我应该只守护进程 myMain.py
还是应该在每个进程生成时守护进程?
这是处理信号处理时可能会出现的一般问题。 Python 信号也不例外,它是操作系统信号的包装器。因此,python中的信号处理取决于操作系统、硬件和许多条件。但是,如何处理这些问题是相似的。
根据本教程,我将引用以下段落:signal – Receive notification of asynchronous system events
Signals are an operating system feature that provide a means of
notifying your program of an event, and having it handled
asynchronously. They can be generated by the system itself, or sent
from one process to another. Since signals interrupt the regular flow
of your program, it is possible that some operations (especially I/O)
may produce error if a signal is received in the middle.
Signals are identified by integers and are defined in the operating
system C headers. Python exposes the signals appropriate for the
platform as symbols in the signal module. For the examples below, I
will use SIGINT and SIGUSR1. Both are typically defined for all Unix
and Unix-like systems.
在我的代码中:
for 循环中的 os.system("python myParsePDB.py -i BP1.pdb -c 1 -s %s" % step)
将执行一段时间,并且会在 I/O 文件上花费一些时间。如果键盘中断传得太快,写入文件后没有异步捕获,信号可能在操作系统中被阻塞,所以我的执行仍然是try
子句for循环。 (在执行期间检测到的错误称为异常,并非无条件地致命:Python Errors and Exceptions)。
因此,让它们异步的最简单方法是等待:
try:
for i in range(0,360, step):
os.system("python myParsePDB.py -i BP1.pdb -c 1 -s %s" % step)
time.sleep(0.2)
except KeyboardInterrupt:
print("Stop me!")
sys.exit(0)
这可能会影响性能,但它保证了在等待 os.system()
执行后可以捕获信号。如果需要更好的性能,您可能还想使用其他 sync/async 函数来解决问题。
更多unix信号参考,请同时查看:Linux Signal Manpage
我有这个名为 myMain.py
的简单 python 脚本来自动执行另一个 python 程序并增加数字,我在 CentOS 7 上 运行 它:
#!/usr/bin/python
import os
import sys
import time
def main():
step_indicator = ""
arrow = ">"
step = 2
try:
for i in range(0,360, step):
step_percentage = float(i)/360.0 * 100
if i % 10 == 0:
step_indicator += "="
os.system("python myParsePDB.py -i BP1.pdb -c 1 -s %s" % step)
print("step_percentage%s%s%.2f" % (step_indicator,arrow,step_percentage)+"%")
except KeyboardInterrupt:
print("Stop me!")
sys.exit(0)
if __name__ == "__main__":
main()
现在我只知道这个脚本是单线程安全的,但我不能用 Ctrl+C
键盘中断来终止它。
我看了一些相关的问题:比如Cannot kill Python script with Ctrl-C and Stopping python using ctrl+c我意识到Ctrl+Z
不会杀死进程,它只是暂停进程并让进程保持在后台。 Ctrl+Break
也适用于我的情况,我认为它只会终止我的主线程但保留子进程。
我还注意到调用 os.system()
会从当前执行的进程中生成一个子进程。同时,我还有 os
文件 I/O 函数并且 os.system("rm -rf legacy/*")
将在 myParsePDB.py
中调用,这意味着此 myParsePDB.py
子进程将生成子进程作为出色地。然后,如果我想在 myMain.py
中捕获 Ctrl+C
,我应该只守护进程 myMain.py
还是应该在每个进程生成时守护进程?
这是处理信号处理时可能会出现的一般问题。 Python 信号也不例外,它是操作系统信号的包装器。因此,python中的信号处理取决于操作系统、硬件和许多条件。但是,如何处理这些问题是相似的。
根据本教程,我将引用以下段落:signal – Receive notification of asynchronous system events
Signals are an operating system feature that provide a means of notifying your program of an event, and having it handled asynchronously. They can be generated by the system itself, or sent from one process to another. Since signals interrupt the regular flow of your program, it is possible that some operations (especially I/O) may produce error if a signal is received in the middle.
Signals are identified by integers and are defined in the operating system C headers. Python exposes the signals appropriate for the platform as symbols in the signal module. For the examples below, I will use SIGINT and SIGUSR1. Both are typically defined for all Unix and Unix-like systems.
在我的代码中:
for 循环中的os.system("python myParsePDB.py -i BP1.pdb -c 1 -s %s" % step)
将执行一段时间,并且会在 I/O 文件上花费一些时间。如果键盘中断传得太快,写入文件后没有异步捕获,信号可能在操作系统中被阻塞,所以我的执行仍然是try
子句for循环。 (在执行期间检测到的错误称为异常,并非无条件地致命:Python Errors and Exceptions)。
因此,让它们异步的最简单方法是等待:
try:
for i in range(0,360, step):
os.system("python myParsePDB.py -i BP1.pdb -c 1 -s %s" % step)
time.sleep(0.2)
except KeyboardInterrupt:
print("Stop me!")
sys.exit(0)
这可能会影响性能,但它保证了在等待 os.system()
执行后可以捕获信号。如果需要更好的性能,您可能还想使用其他 sync/async 函数来解决问题。
更多unix信号参考,请同时查看:Linux Signal Manpage