繁体   English   中英

终止使用子进程 python 挂起的 python 程序

[英]terminate a python program when it hanged using subprocess python

我有一个 main.py,当另一个程序(test.py,在同一目录中)被挂起时,它会打开一个新的 cmd(子进程)。 为了确定test.py是否挂起,我使用了最新修改时间(os.path.getmtime(test.log))日志文件,test.log(test.py不断向这个test.log文件写入行)

现在我有几件事要做:

  1. 当 test.py 挂起时打开一个新的 cmd
  2. 在新打开的 cmd 中运行 test.py
  3. 当我们打开超过 2 个 cmd 时杀死 cmd
# test.py
import time
print("test.py started...")
time.sleep(1000) # this is so long because it is behaving like test.py is hanged
print("test.py is finished...") # before this line i want to close this terminal
# main.py
import datetime
import shelx
import subprocess
def modified_time():
    file_date = time.ctime(os.path.getmtime('test.log'))
    file_date = datetime.datetime.strptime(file_date, "%a %b %d %H:%M:%S %Y")
    delta = datetime.datetime.now() - file_date
    t = delta.total_seconds()
    return divmod(t, 60)[0]  # return minutes

cmd2 = "python test.py"
while(True):
    if modified_time() >= 2:
        b = subprocess.Popen(["start", "/wait", "cmd.exe", "/k", cmd2], shell=True)
        (output, err) = b.communicate()
        # b.wait()
        pid_lst.append(b.pid)
        print(pid_lst)
        while len(pid_lst) > 2:
            x = pid_lst.pop(0)
            #cmd_2  = f"WMIC PROCESS WHERE \"ProcessID={str(x)}\" CALL TERMINATE"
            cmd_2 = f"taskkill /PID {str(x)} /F"
            args = shlex.split(cmd_2)
            try:
                y = subprocess.Popen(args, shell=False)
                print("killed ", x)
            except Exception as e:
                print(e.args)

在 linux 下,我得到了 shell 的 pid,并且 Python 进程仍然存在。

然后要让 python 代码在没有 shell 的情况下运行,我需要指定 python 可执行文件的完整路径名:

# main.py
import datetime
import subprocess
import time
import os
import logging
import sys

def modified_time():
    file_date = time.ctime(os.path.getmtime('test.log'))
    file_date = datetime.datetime.strptime(file_date, "%a %b %d %H:%M:%S %Y")
    delta = datetime.datetime.now() - file_date
    # print(f'{file_date=}   {datetime.datetime.now()=}')
    t = delta.total_seconds()
    return  t # divmod(t, 60)[0]  # return minutes


current_dir = os.getcwd()
python_executable = sys.executable

cmd2 = f"{python_executable} test.py"

logging.basicConfig(filename='test.log', level=logging.DEBUG)
logging.error("test.log touched")

b = None

while(True):
    print(f'{modified_time()=}')
    time.sleep(.8)
    
    if modified_time() >= 2:
         
        if b is not None:
            try:
                print("killing ", b.pid)
                b.kill()
            except Exception as e:
                print(e.args)
                break
                
        b = subprocess.Popen(cmd2.split(' '), shell=False)

与稍作改动的 test.py 一起使用

# test.py
import time
import logging
import os

current_dir = os.getcwd()

logging.basicConfig(filename=f'{current_dir}/test.log', level=logging.DEBUG)

logging.error("test.py started...")

time.sleep(1000) # this is so long because it is behaving like test.py is hanged

logging.info("test.py is finished...") # before this line i want to close this terminal

我还确保从启动 main.py 中接触到日志文件。 我不明白 pid 的列表,所以我用 b 的 None 初始化替换它。

两个文件都在同一个目录中。 如果它们位于单独的目录中,我预计需要进行一些更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM