我有一个命令行程序,我希望它一直运行直到再次打开它,因此基本上是一个程序,该程序首先检查当前是否已在运行自身实例并杀死它。
我尝试了os.system('TASKKILL /F /IM program.exe')
,但事实证明它很愚蠢,因为它也会自杀。
答案 0 :(得分:1)
确保应用程序只有一个实例的最可靠方法是在已知(固定)位置创建pid文件。该位置通常位于您的应用程序数据文件夹中或临时目录中。在启动时,您应该检查pid文件是否存在以及包含在其中的pid是否仍然存在并引用您的目标进程。如果存在,则向其发送终止信号,然后在启动应用程序的其余部分之前,使用当前pid覆盖文件。
为了更加安全,您可能要等到之前的过程完全终止。这可以通过等待/轮询来检查该pid的进程是否仍然存在,或者通过轮询被杀死的进程以删除其自己的pid文件来完成。如果进程关闭的时间很长,并且您希望在关闭旧进程的同时允许当前进程已经开始工作,则可能需要后者。
答案 1 :(得分:1)
您可以使用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:
# ...
答案 2 :(得分:0)
由于我的工作站无法访问互联网并且安装软件包很乱,所以我最终提出了以下解决方案:
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命令的输出打印到一个文件中,然后检查该文件以查看是否有一个runnig 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
答案 3 :(得分:-1)
您可以使用已经运行的实例的进程ID。
import os
os.system("taskkill /pid <ProcessID>")