Python脚本可以';不能通过Ctrl+终止;C或Ctrl+;打破

Python脚本可以';不能通过Ctrl+终止;C或Ctrl+;打破,python,asynchronous,scripting,operating-system,signal-handling,Python,Asynchronous,Scripting,Operating System,Signal Handling,我有一个名为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):

我有一个名为
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+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中的信号处理依赖于操作系统、硬件和许多条件。然而,如何处理这些问题是相似的

根据本教程,我将引用以下段落:

信号是一种操作系统功能,它提供了 将事件通知程序并处理它 异步的。它们可以由系统本身生成,也可以发送 从一个过程到另一个过程。因为信号中断了正常的流动 在您的程序中,某些操作(特别是I/O)可能 如果在中间接收到信号,则可能产生误差。 信号由整数标识,并在操作系统中定义 系统C标题。Python公开适用于 平台作为信号模块中的符号。对于下面的示例,我 将使用SIGINT和SIGUSR1。这两者通常都是为所有Unix系统定义的 和类Unix系统

在我的代码中:

os.system(“python myParsePDB.py-i BP1.pdb-c 1-s%s”%step)
for循环内部将执行一段时间,并在i/O文件上花费一些时间。如果键盘中断传递太快,并且在写入文件后没有异步捕获,则信号可能会在操作系统中被阻止,因此我的执行仍将保留循环的
try
子句。(执行期间检测到的错误称为异常,并且不是无条件致命的:)

因此,使它们异步的最简单方法是等待:

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信号参考,请参阅:

是否需要在子进程中运行
myParsePDB
?难道你不能把它作为一个普通的模块来编写吗?你可以从这个脚本中调用函数,而不用
os.system
?您应该能够使用@TadhgMcDonald Jensen执行
rm
功能。有必要运行
myParsePDB
rm
只是
myParsePDB
中的一小部分。