Python脚本如何批量终止异常进程

wen python案例 29

Python脚本如何批量终止异常进程(附完整代码)

目录导读

  1. 为什么需要批量终止异常进程?
  2. Python批量终止进程的核心原理
  3. 实战:基于进程名批量终止脚本
  4. 进阶:基于CPU/内存占用率智能清理
  5. 常见问题与避坑指南(Q&A)
  6. 总结与最佳实践建议

为什么需要批量终止异常进程?

在实际运维或开发工作中,我们常常遇到以下场景:

Python脚本如何批量终止异常进程

  • 某个Python爬虫任务崩溃后留下大量僵尸进程,占满系统内存
  • 测试环境中的多个浏览器实例未被正确关闭,导致新进程无法启动
  • 服务器上的多个同类型服务出现死锁,需要一次性清理

手动执行kill命令逐个处理既低效又不安全,而通过Python脚本批量终止异常进程可同时实现:
速度优势:毫秒级扫描并结束成百上千个进程
精准控制:通过进程名、运行时长、资源占用等多维度过滤
错误隔离:避免误杀系统关键进程(如systemd


Python批量终止进程的核心原理

1 跨平台方案选择

操作系统 底层命令 Python模块 权限要求
Windows taskkill psutil / os.system 管理员权限
Linux/macOS kill / pkill psutil / subprocess root或sudo

2 推荐使用psutil

psutil(Process and System Utilities)能直接获取进程的PID、名称、CPU/内存占用、运行时间等属性,且无需调用系统命令,兼容性极佳。

pip install psutil

3 关键函数说明

  • psutil.process_iter():遍历所有运行中的进程
  • psutil.Process(pid):获取某个PID的完整对象
  • process.terminate()process.kill():终止进程(前者发送SIGTERM,后者强制SIGKILL)

实战:基于进程名批量终止脚本

以下脚本可直接复制使用,它会根据进程名关键词终止所有匹配的非系统进程。

import psutil
import os
import sys
def batch_kill_by_name(process_name, exclude_pids=None):
    """
    根据进程名批量终止进程
    :param process_name: 进程名关键词(如 "chrome" 或 "python.exe")
    :param exclude_pids: 需要保留的PID列表(如当前脚本自身PID)
    """
    if exclude_pids is None:
        exclude_pids = [os.getpid()]
    killed_count = 0
    for proc in psutil.process_iter(['pid', 'name']):
        try:
            if process_name.lower() in proc.info['name'].lower():
                if proc.info['pid'] not in exclude_pids:
                    proc.terminate()  # 先尝试优雅终止
                    print(f"✅ 已终止进程:{proc.info['name']} (PID: {proc.info['pid']})")
                    killed_count += 1
        except (psutil.NoSuchProcess, psutil.AccessDenied):
            continue
    print(f"\n总共终止了 {killed_count} 个进程")
if __name__ == "__main__":
    target = input("请输入要终止的进程名(或关键词):").strip()
    if not target:
        print("输入不能为空!")
        sys.exit(1)
    batch_kill_by_name(target)

使用方法

sudo python kill_by_name.py
输入:python          # 将终止所有名字包含"python"的进程(注意会包括脚本自身?已排除)

注意:在Linux/macOS上需要sudo权限才能终止其他用户的进程。


进阶:基于CPU/内存占用率智能清理

常见需求:终止占用超过80% CPU的异常进程,或运行超过2小时的闲置进程。

import psutil
import time
def kill_high_resource_processes(cpu_threshold=80, mem_threshold=80):
    killed = []
    for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
        try:
            cpu = proc.info['cpu_percent'] or 0
            mem = proc.info['memory_percent'] or 0
            if cpu > cpu_threshold or mem > mem_threshold:
                proc.kill()  # 异常进程直接强杀
                killed.append((proc.info['name'], proc.info['pid']))
                print(f"⚠️ 强杀高危进程:{proc.info['name']} CPU={cpu}% MEM={mem}%")
        except (psutil.NoSuchProcess, psutil.AccessDenied):
            pass
    return killed
if __name__ == "__main__":
    # 设置阈值:CPU>80% 或 内存>80%
    result = kill_high_resource_processes(80, 80)
    print(f"本次清理了 {len(result)} 个异常进程")

常见问题与避坑指南(Q&A)

Q1:为什么我的脚本无法终止某些进程?

A:常见原因有:

  1. 权限不足:目标进程由其他用户启动,需使用sudo运行脚本
  2. 系统保护进程:如systemdinit等进程无法被普通用户终止
  3. 进程已僵尸化:部分已死亡的进程(Zombie)无法被kill,需通过父进程wait()清理

Q2:如何避免误杀关键系统进程?

A:建议加入“白名单”机制:

SAFE_PROCESSES = ['systemd', 'sshd', 'nginx', 'mysql']
if proc.info['name'] not in SAFE_PROCESSES:
    # 执行终止操作

Q3:脚本运行后提示“NoSuchProcess”错误怎么办?

A:这是因为进程列表在遍历过程中被其他程序终止了,使用try-except捕获即可,代码中已包含处理。

Q4:如何终止某个用户启动的所有进程?

A:可通过proc.username()获取进程所属用户:

for proc in psutil.process_iter(['pid', 'name', 'username']):
    if 'target_user' in proc.info['username']:
        proc.kill()

总结与最佳实践建议

核心要点

  • 优先使用psutil:比os.system("taskkill /f /im xxx.exe")更安全可控
  • terminate()kill():给进程优雅退出的机会,避免数据丢失
  • 日志记录:将终止的进程信息写入文件,便于后续追踪

完整企业级脚本结构建议

读取配置文件(白名单、阈值、日志路径)
2. 多轮扫描(每次间隔2秒,共3次确认异常)
3. 发送终止指令并记录日志
4. 钉钉/邮件通知管理员

性能提示

当系统有上万进程时,psutil.process_iter()一次性遍历可能耗时较长,可以指定遍历属性:

proc_info = proc.as_dict(attrs=['pid', 'name', 'cpu_percent'])

延伸阅读

通过以上Python脚本,您可以在几秒钟内完成过去需要手动操作的进程清理工作,极大提升服务器运维效率,建议先在测试环境验证后,再部署到生产服务器。

抱歉,评论功能暂时关闭!