Python 如何使程序关闭它';启动时,当前正在运行的实例是什么?

Python 如何使程序关闭它';启动时,当前正在运行的实例是什么?,python,process,os.system,taskkill,Python,Process,Os.system,Taskkill,我有一个命令行程序,我想一直运行,直到我再次打开它,所以基本上是一个程序,它首先检查当前是否有任何已经运行的实例,然后杀死它 我试过os.system('TASKKILL/F/IM program.exe'),但结果很愚蠢,因为它也会杀死自己。您可以使用已经运行的实例的进程id import os os.system("taskkill /pid <ProcessID>") 导入操作系统 操作系统(“taskkill/pid”) 确保应用程序只有一个实例的最可靠方法是在已知(固定)

我有一个命令行程序,我想一直运行,直到我再次打开它,所以基本上是一个程序,它首先检查当前是否有任何已经运行的实例,然后杀死它


我试过
os.system('TASKKILL/F/IM program.exe')
,但结果很愚蠢,因为它也会杀死自己。

您可以使用已经运行的实例的进程id

import os
os.system("taskkill /pid <ProcessID>")
导入操作系统
操作系统(“taskkill/pid”)

确保应用程序只有一个实例的最可靠方法是在已知(固定)位置创建pid文件。此位置通常位于应用程序数据文件夹或临时目录中。在启动时,您应该检查pid文件是否存在,以及其中包含的pid是否仍然存在并引用您的目标进程。如果存在,则向其发送终止信号,然后在启动应用程序的其余部分之前,使用当前pid覆盖该文件


为了更加安全,您可能需要等待上一个进程完全终止。这可以通过等待/轮询来检查具有该pid的进程是否仍然存在,或者通过轮询被终止的进程来删除其自己的pid文件来实现。如果进程关闭非常长,并且您希望在旧进程关闭时允许当前进程已经开始工作,则后者可能是必需的。

您可以使用
psutil
库。它只是迭代所有正在运行的进程,用特定的文件名过滤进程,如果它们的PID与当前进程不同,那么它将杀死它们。考虑到您有正确的进程文件名,它也可以在任何平台上运行

import psutil

process_to_kill = "program.exe"

# get PID of the current process
my_pid = os.getpid()

# iterate through all running processes
for p in psutil.process_iter():
    # if it's process we're looking for...
    if p.name() == process_to_kill:
        # and if the process has a different PID than the current process, kill it
        if not p.pid == my_pid:
            p.terminate()
如果只是程序文件名不够唯一,您可以使用方法
Process.exe()
,该方法返回进程映像的完整路径:

process_to_kill = "c:\some\path\program.exe"

for p in psutil.process_iter():
    if p.exe() == process_to_kill:
         # ...

由于我的工作站无法访问internet,而且安装软件包的过程非常混乱,因此我最终提出了以下解决方案:

import os

os.system('tasklist > location/tasks.txt')
with open('location/tasks.txt', 'r') as pslist:
    for line in pslist:
        if line.startswith('python.exe'):
            if line.split()[1] != str(os.getpid()):
                os.system(f'TASKKILL /F /PID {line.split()[1]}')
                break
os.remove('location/tasks.txt')
它将tasklist命令的输出输出打印到一个文件中,然后检查该文件,以查看是否有一个运行的python进程与它自己的进程具有不同的PID

编辑:我想我可以用
popen
来编辑,所以它比较短,而且没有涉及任何文件:

import os

for line in os.popen('tasklist').readlines():
    if line.startswith('python.exe'):
        if line.split()[1] != str(os.getpid()):
            os.system(f'taskkill /F /PID {line.split()[1]}')
            break

如何找到它的PID?您可以使用psutil通过进程名获取PID
taskkill
将使其依赖于Windows平台,因此我建议使用
psutils
库。或者您的意思是
program.exe
本身应该检查是否有任何它已经运行的实例并将其杀死?@Dawiderency Yes请不要忘记将解决问题的任何答案标记为已接受答案。它将帮助其他人寻找解决方案,以找到答案。@Dawiderenchy看看我自己的答案。。。感谢您的解决方案。如果您使用p.name()来标识进程,请小心,因为不相关的进程可能具有相同的名称。使用p.exe()来匹配可执行路径可能更安全。请检查我的答案,我建议使用
cmdline()
方法。好的,
exe
方法看起来更合适,谢谢你的建议!但这样做会杀死任何正在运行的Python解释器,即使它正在执行不同的脚本。也许你没问题,你应该意识到这一点。是的,我知道。我不希望在短时间内运行多个脚本,但如果将来我想运行,我只会将第一个实例的PID公开给一个文件,然后检查该文件。