Python脚本不能通过Ctrl+C或Ctrl+B终止

2024-09-30 00:34:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个简单的python脚本myMain.py来自动执行另一个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-CStopping python using ctrl+c我意识到{}并没有杀死进程,它只是暂停进程并将进程保留在后台。Ctrl+Break也适用于我的情况,我认为它只终止了我的主线程,但保留了子进程。在

我还注意到,调用os.system()将从当前正在执行的进程中生成一个子进程。同时,我还有os文件I/O函数,os.system("rm -rf legacy/*")将在myParsePDB.py中调用,这意味着myParsePDB.py子进程也将生成子进程。那么,如果我想在myMain.py中捕获Ctrl+C,我应该只守护myMain.py还是应该在每个进程生成时守护它们?在


Tags: pyimport脚本进程osmainstepsys
1条回答
网友
1楼 · 发布于 2024-09-30 00:34:00

这是一个在处理信号处理时可能会出现的一般问题。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子句。(在执行过程中检测到的错误称为异常,并且不是无条件致命的: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()的执行之后可以捕获信号。如果需要更好的性能,您可能还希望使用其他同步/异步函数来解决问题。在

有关更多的unix信号参考,请参阅:Linux Signal Manpage

相关问题 更多 >

    热门问题