在 Windows 中用 shell=True 启动后台进程

我正在尝试从 Python 启动一个服务器来对 Java 中的 PMML 模型进行评分。计算完成后,我希望能够关闭该服务器(即终止进程)。我使用的是 Windows 10。但是,我发现它比我想象的更令人困惑。


首先,我像这样启动服务器:


p = subprocess.Popen('START /B java -jar openscoring-server-executable-1.4.3.jar',

                      shell=True)

我让它在后台运行,以便在用户运行脚本时不显示 CMD 窗口。为了使这成为可能,我认为该shell=True参数是必要的。


当我尝试使用此行终止进程时:


subprocess.call("TASKKILL /F /PID {pid} /T".format(pid=p.pid))

该进程仍在运行。实际上,p.pid任务管理器中甚至不存在返回的PID 。在尝试使用此答案中提供的解决方案时,我已经确认了这一点:


def kill(proc_pid):

    process = psutil.Process(proc_pid)

    for proc in process.children(recursive=True):

        proc.kill()

    process.kill()


kill(p.pid)

这将返回异常NoSuchProcess: no process found with pid 5280。


我可以通过任务管理器看到分配给我想杀死的进程的 PID:

http://img4.mukewang.com/60e3bca3000106b111650233.jpg

但我不知道如何在 Python 中找到那个 PID 来终止它。我在网站上找到的答案似乎不适用于后台运行的进程。


编辑:


我认为如果我能够使用 运行命令,这可以解决shell=False,但由于START /B. 这将返回一个错误:


p = subprocess.Popen(['START', '/B', 'java', '-jar openscoring-server-executable-1.4.3.jar'])


哆啦的时光机
浏览 280回答 3
3回答

心有法竹

您可以在此处搜索您的应用程序并关闭。import psutilimport osls = []for p in psutil.process_iter():    try:        name = p.name()        cmdline = p.cmdline()        exe = p.exe()        pid = p.pid    except (psutil.AccessDenied, psutil.ZombieProcess):        continue    except psutil.NoSuchProcess:        continue

长风秋雁

此行不起作用,因为您需要提供所有参数和确切的字符串。if process.cmdline() == args:我将其更改为包括一些字符串和部分字符串:def process_get(*args):        """Returns the process matching ``args``.        Relies on ``args`` matching the argument list of the process to find.        Args:            *args: process arguments, e.g. ["java", "jar", "partialjarname"]        Returns:            :obj:`process`        """        import psutil        for process in psutil.process_iter():            try:                if all(x in " ".join(process.cmdline()) for x in args):                    return process            except psutil.AccessDenied:                pass        return None

12345678_0001

如果您无法找出正确的 PID,我可能有一个替代解决方案,利用您用于启动该过程的参数。它不是那么好,因为您将遍历流程树直到找到匹配项,但这样它肯定会找到流程。请记住,如果您有多个运行相同参数的进程,这可能不会总是返回正确的进程。def process_get(*args):    """Returns the process matching ``args``.    Relies on ``args`` matching the argument list of the process to find.    Args:        *args: process arguments, e.g. ["java", "-jar", "somejar.jar"]    Returns:        :obj:`process`    """    import psutil    for process in psutil.process_iter():        try:            if process.cmdline() == args:                return process        except psutil.AccessDenied:            pass    return None
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python