为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

哆啦的时光机 2021-06-29 13:20:31
我正在尝试从 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:但我不知道如何在 Python 中找到那个 PID 来终止它。我在网站上找到的答案似乎不适用于后台运行的进程。编辑:我认为如果我能够使用 运行命令,这可以解决shell=False,但由于START /B. 这将返回一个错误:p = subprocess.Popen(['START', '/B', 'java', '-jar openscoring-server-executable-1.4.3.jar'])
查看完整描述

3 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

您可以在此处搜索您的应用程序并关闭。


import psutil

import os


ls = []

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


查看完整回答
反对 回复 2021-07-06
?
长风秋雁

TA贡献1757条经验 获得超7个赞

此行不起作用,因为您需要提供所有参数和确切的字符串。


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


查看完整回答
反对 回复 2021-07-06
?
12345678_0001

TA贡献1802条经验 获得超5个赞

如果您无法找出正确的 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


查看完整回答
反对 回复 2021-07-06
  • 3 回答
  • 0 关注
  • 279 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号