在Python开发中,我们经常会遇到需要启动外部可执行程序,并且后续要获取该程序运行产生的进程PID的情况,比如需要监控进程状态、超时后终止进程等场景。下面介绍两种常用的实现方式,开发者可以根据实际需求选择。

方案一:使用psutil库实现
psutil是一个跨平台的进程和系统监控库,支持Windows、Linux、macOS等系统,功能强大且使用简单,推荐优先使用这种方式。
前置准备
首先需要通过pip安装psutil库:
# 安装命令 pip install psutil
实现步骤
核心思路是先启动可执行文件,再通过遍历系统所有进程,匹配进程的可执行文件名,筛选出目标进程拿到PID。示例代码如下:
import psutil
import subprocess
import time
def get_pid_by_exe_name(exe_name):
"""
通过可执行文件名获取进程PID
:param exe_name: 可执行文件名,比如notepad.exe、chrome
:return: 匹配到的PID列表,没有则返回空列表
"""
pid_list = []
# 遍历系统内所有进程
for proc in psutil.process_iter():
try:
# 获取进程的可执行文件路径
proc_exe = proc.exe()
# 判断文件名是否匹配,兼容不同系统的路径分隔符
if exe_name.lower() in proc_exe.lower():
pid_list.append(proc.pid)
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
# 忽略进程不存在、无权限访问、僵尸进程的异常
pass
return pid_list
if __name__ == "__main__":
# 启动目标可执行文件,这里以Windows的记事本为例
subprocess.Popen("notepad.exe")
# 等待进程启动完成
time.sleep(1)
# 获取PID
target_pids = get_pid_by_exe_name("notepad.exe")
print(f"匹配到的进程PID列表:{target_pids}")这种方式的好处是跨平台兼容性好,不需要依赖系统自带的特殊命令,异常处理完善,适合生产环境使用。
方案二:使用subprocess结合系统命令实现
如果不想额外安装第三方库,也可以结合系统自带的进程查询命令实现,不过这种方式需要根据不同系统写不同的命令逻辑。
Windows系统实现
Windows下可以使用tasklist命令查询进程信息,示例代码如下:
import subprocess
import re
def get_pid_win(exe_name):
"""
Windows下通过可执行文件名获取PID
"""
# 执行tasklist命令,筛选包含目标exe名的行
cmd = f"tasklist /fi \"imagename eq {exe_name}\" /fo csv /nh"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
pid_list = []
# 解析命令输出,提取PID
for line in result.stdout.strip().split("\n"):
if exe_name.lower() in line.lower():
# 匹配CSV格式中的PID字段
match = re.search(r',"(\d+)"', line)
if match:
pid_list.append(int(match.group(1)))
return pid_list
if __name__ == "__main__":
subprocess.Popen("notepad.exe")
import time
time.sleep(1)
print(f"Windows下获取的PID:{get_pid_win('notepad.exe')}")Linux/macOS系统实现
类Unix系统下可以使用pgrep命令快速查询,示例代码如下:
import subprocess
def get_pid_linux(exe_name):
"""
Linux/macOS下通过可执行文件名获取PID
"""
# pgrep命令直接返回匹配进程名的PID
cmd = f"pgrep -x {exe_name}"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
pid_str = result.stdout.strip()
if pid_str:
return [int(pid) for pid in pid_str.split("\n") if pid]
return []
if __name__ == "__main__":
# 以启动sleep进程为例
subprocess.Popen(["sleep", "100"])
import time
time.sleep(1)
print(f"Linux下获取的PID:{get_pid_linux('sleep')}")两种方式对比
下面是两种方案的对比,方便开发者选择:
| 对比项 | psutil方案 | 系统命令方案 |
|---|---|---|
| 跨平台性 | 好,支持所有主流系统 | 差,需要分系统写逻辑 |
| 依赖程度 | 需要安装第三方库 | 仅依赖系统自带命令 |
| 稳定性 | 高,异常处理完善 | 一般,命令输出格式变化可能影响解析 |
注意事项
- 如果系统中有多个同名可执行文件进程运行,两种方法都会返回所有匹配到的PID,需要根据其他条件进一步筛选。
- 使用psutil时,部分进程可能因为权限不足无法访问,需要在代码中做好异常捕获。
- 启动进程后建议等待一小段时间再查询PID,避免进程还没启动完成导致查询不到。
Python进程PID可执行文件名psutilsubprocess修改时间:2026-05-31 23:56:57