linux僵尸线程清理

news2024/11/29 20:53:22

文章目录

    • 1.cleanup_zombies.sh脚本
    • 2.terminate_zombie_parents.sh:
    • 3.监控僵尸进程monitor_zombies.sh:
    • 4. 执行权限
    • 5.定时处理
    • 6.使用go执行


1.cleanup_zombies.sh脚本

#!/bin/bash

echo "检测并尝试清理僵尸进程..."

# 查找所有僵尸进程及其父进程
zombies=$(ps -eo pid,ppid,stat,cmd | grep 'Z' | awk '$3 ~ /Z/ {print $1","$2}')
if [ -z "$zombies" ]; then
  echo "没有检测到僵尸进程!"
  exit 0
fi

echo "发现以下僵尸进程:"
echo "$zombies" | tr ',' '\t' | awk '{printf "僵尸PID: %s 父进程PID: %s\n", $1, $2}'

# 遍历每个僵尸进程
echo "$zombies" | while IFS=',' read -r zombie_pid parent_pid; do
  echo "尝试处理父进程 $parent_pid..."
  
  # 向父进程发送 SIGCHLD 信号,通知其处理僵尸
  kill -SIGCHLD "$parent_pid" 2>/dev/null
  
  # 检查父进程是否仍在运行
  if ps -p "$parent_pid" > /dev/null 2>&1; then
    echo "父进程 $parent_pid 仍在运行,可能需要手动检查。"
  else
    echo "父进程 $parent_pid 不存在,僵尸进程 $zombie_pid 将被 init 清理。"
  fi
done

echo "僵尸进程清理完成。"

2.terminate_zombie_parents.sh:

#!/bin/bash

echo "检测并尝试终止僵尸进程的父进程..."

# 查找所有僵尸进程及其父进程
zombies=$(ps -eo pid,ppid,stat,cmd | grep 'Z' | awk '$3 ~ /Z/ {print $1","$2}')
if [ -z "$zombies" ]; then
  echo "没有检测到僵尸进程!"
  exit 0
fi

echo "发现以下僵尸进程:"
echo "$zombies" | tr ',' '\t' | awk '{printf "僵尸PID: %s 父进程PID: %s\n", $1, $2}'

# 遍历每个僵尸进程
echo "$zombies" | while IFS=',' read -r zombie_pid parent_pid; do
  echo "尝试终止父进程 $parent_pid..."

  # 杀死父进程
  kill -9 "$parent_pid" 2>/dev/null

  if [ $? -eq 0 ]; then
    echo "父进程 $parent_pid 已终止,僵尸进程 $zombie_pid 将被系统清理。"
  else
    echo "无法终止父进程 $parent_pid,请手动检查。"
  fi
done

echo "父进程终止完成,僵尸进程将被清理。"

3.监控僵尸进程monitor_zombies.sh:

#!/bin/bash

logfile="/var/log/zombie_cleanup.log"
echo "[$(date)] 开始检测僵尸进程..." >> "$logfile"

# 查找僵尸进程
zombies=$(ps -eo pid,ppid,stat,cmd | grep 'Z' | awk '$3 ~ /Z/ {print $1","$2}')
if [ -z "$zombies" ]; then
  echo "[$(date)] 没有僵尸进程。" >> "$logfile"
  exit 0
fi

echo "[$(date)] 发现以下僵尸进程:" >> "$logfile"
echo "$zombies" | tr ',' '\t' | awk '{printf "僵尸PID: %s 父进程PID: %s\n", $1, $2}' >> "$logfile"

# 尝试清理
echo "$zombies" | while IFS=',' read -r zombie_pid parent_pid; do
  echo "[$(date)] 尝试处理父进程 $parent_pid..." >> "$logfile"
  kill -SIGCHLD "$parent_pid" 2>/dev/null
  
  if ! ps -p "$parent_pid" > /dev/null 2>&1; then
    echo "[$(date)] 父进程 $parent_pid 不存在,僵尸进程 $zombie_pid 将被系统清理。" >> "$logfile"
  else
    echo "[$(date)] 父进程 $parent_pid 仍在运行,请手动检查。" >> "$logfile"
  fi
done

echo "[$(date)] 僵尸清理完成。" >> "$logfile"

4. 执行权限

chmod +x cleanup_zombies.sh
chmod +x terminate_zombie_parents.sh
chmod +x monitor_zombies.sh

5.定时处理

运行 :手动清理僵尸:./cleanup_zombies.sh 强制终止父进程;
bash 定期监控(结合 cron 使用): 将 monitor_zombies.sh 添加到 cron,每分钟运行一次:
crontab -e  * * * * * /path/to/monitor_zombies.sh

6.使用go执行

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"strings"
)

// ZombieProcess 结构体用于存储僵尸进程的 PID 和父进程的 PPID
type ZombieProcess struct {
	PID  string
	PPID string
}

func main() {
	fmt.Println("检测并尝试清理僵尸进程...")

	// 第一步:查找僵尸进程
	zombies, err := findZombies()
	if err != nil {
		fmt.Printf("无法检测僵尸进程: %v\n", err)
		return
	}

	// 如果没有僵尸进程
	if len(zombies) == 0 {
		fmt.Println("没有检测到僵尸进程!")
		return
	}

	// 输出检测到的僵尸进程信息
	fmt.Println("发现以下僵尸进程:")
	for _, z := range zombies {
		fmt.Printf("僵尸PID: %s 父进程PID: %s\n", z.PID, z.PPID)
	}

	// 第二步:尝试清理每个僵尸进程
	for _, z := range zombies {
		fmt.Printf("尝试通知父进程 %s 清理僵尸进程 %s...\n", z.PPID, z.PID)
		err := notifyParent(z.PPID) // 通知父进程
		if err != nil {
			fmt.Printf("无法通知父进程 %s: %v\n", z.PPID, err)
			continue
		}

		// 第三步:验证父进程是否仍然活跃
		if isParentActive(z.PPID) {
			fmt.Printf("父进程 %s 仍在运行,请手动检查。\n", z.PPID)
		} else {
			fmt.Printf("父进程 %s 不存在,僵尸进程 %s 将由系统清理。\n", z.PPID, z.PID)
		}
	}

	fmt.Println("僵尸进程清理完成。")
}

// findZombies 使用 `ps` 命令查找僵尸进程
func findZombies() ([]ZombieProcess, error) {
	// 执行 ps 命令,列出所有进程的 PID, PPID 和状态
	cmd := exec.Command("ps", "-eo", "pid,ppid,stat")
	output, err := cmd.Output()
	if err != nil {
		return nil, fmt.Errorf("执行 ps 命令失败: %w", err)
	}

	// 用于存储检测到的僵尸进程
	var zombies []ZombieProcess
	scanner := bufio.NewScanner(bytes.NewReader(output))
	for scanner.Scan() {
		line := scanner.Text()
		fields := strings.Fields(line)

		// 检查进程状态是否为 'Z'(僵尸进程)
		if len(fields) >= 3 && strings.Contains(fields[2], "Z") {
			zombies = append(zombies, ZombieProcess{
				PID:  fields[0], // 僵尸进程的 PID
				PPID: fields[1], // 僵尸进程的父进程 ID
			})
		}
	}

	if err := scanner.Err(); err != nil {
		return nil, fmt.Errorf("解析 ps 命令输出失败: %w", err)
	}

	return zombies, nil
}

// notifyParent 向父进程发送 SIGCHLD 信号,通知其处理僵尸进程
func notifyParent(ppid string) error {
	// 使用 kill 命令发送 SIGCHLD 信号
	cmd := exec.Command("kill", "-SIGCHLD", ppid)
	err := cmd.Run()
	if err != nil {
		return fmt.Errorf("发送 SIGCHLD 失败: %w", err)
	}
	return nil
}

// isParentActive 检查父进程是否仍然活跃
func isParentActive(ppid string) bool {
	// 使用 ps 命令检查父进程是否存在
	cmd := exec.Command("ps", "-p", ppid)
	err := cmd.Run()
	return err == nil
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249989.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端面试题-1(详解事件循环)

1.了解浏览器的进程模型 1.什么是进程? 程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程 每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。 2.什么是线程&#xff1f…

http的文件上传和下载原理

目录 一:上传 1:http请求格式 2:文件上传类型分析 1:md5秒传 2:分片上传 1. 什么是分片上传 2. 分片上传的场景 3:断点续传 1. 什么是断点续传 2. 应用场景 3. 实现断点续传的核心逻辑 4. 实现流…

【计算机视觉】图像基本操作

1. 数字图像表示 一幅尺寸为MN的图像可以用矩阵表示,每个矩阵元素代表一个像素,元素的值代表这个位置图像的亮度;其中,彩色图像使用3维矩阵MN3表示;对于图像显示来说,一般使用无符号8位整数来表示图像亮度&…

VSCode 下载 安装

VSCode【下载】【安装】【汉化】【配置C环境(超快)】(Windows环境)-CSDN博客 Download Visual Studio Code - Mac, Linux, Windowshttps://code.visualstudio.com/Downloadhttps://code.visualstudio.com/Download 注意&#xff0…

【Python入门】Python数据类型

文章一览 前言一、变量1.1.如何使用变量1.2.如何定义变量的名字(标识符) 二、数据类型2.1 整型数据2.2 浮点型数据2.3 布尔型(bool)数据2.4 复数型数据2.5 字符串类型1 > 字符串相加(合并)(&…

算法基础 - 高斯牛顿法(曲线拟合)

文章目录 1. 高斯牛顿法发展历程2、问题的引出3、高斯牛顿法的前世3.1、一阶,二阶梯度法共有原理3.2、最速下降法(一阶梯度法)3.3、牛顿法(二阶梯度法) 4、高斯牛顿法4.1 高斯牛顿法的思想4.2 最小二乘问题4.3 高斯牛顿…

Vue+Element Plus实现自定义表单弹窗

目录 一、基本框架 1.父组件index.vue 2.子组件FormPop.vue 二、细节补充 1)input、textarea、select、input number 2)daterange、date、monthrange 3)数据定义 4)没改样式的效果 5)最终效果 三、最终代码 …

VMware Workstation Pro下载安装及简单设置

VMware Workstation Pro下载 方法一:官网下载 https://support.broadcom.com/group/ecx/productdownloads?subfamilyVMwareWorkstationPro账号请自行注册,选择最新版本17.6.1 下载后用md5sum_x64.exe验证下载的文件完整性 方法二 百度网盘 通过网…

ospf协议(动态路由协议)

ospf基本概念 定义 OSPF 是典型的链路状态路由协议,是目前业内使用非常广泛的 IGP 协议之一。 目前针对 IPv4 协议使用的是 OSPF Version 2 ( RFC2328 );针对 IPv6 协议使用 OSPF Version 3 ( RFC2740 )。…

数据结构之循环链表和栈

一、循环链表 1、概念 循环链表:就是首尾相连的链表,通过任意一个节点,都能将整个链表遍历一遍 分类:单向循环链表、双向循环链表 2、单向循环链表的类格式 单向循环链表也就是单向链表的最后一个节点的next域不再为None,而是…

linux安装部署mysql资料

安装虚拟机 等待检查完成 选择中文 软件选择 网络和主机名 开始安装 设置root密码 ADH-password 创建用户 等待安装完成 重启 接受许可证 Centos 7 64安装完成 安装mysql开始 Putty连接指定服务器 在 opt目录下新建download目录 将mysql文件传到该目录下 查看linux服务器的…

HTML 霓虹灯开关效果

HTML 霓虹灯开关效果 1.简介&#xff1a;该代码为纯html&#xff0c;CSS写在了内部&#xff0c;不需要额外引入&#xff0c;霓虹灯开关效果很漂亮&#xff0c;应用在个人物联网项目中是一个比较不错的选择。 2.运行效果&#xff1a; 3.源码&#xff1a; <!DOCTYPE html&g…

uniapp开发支付宝小程序自定义tabbar样式异常

解决方案&#xff1a; 这个问题应该是支付宝基础库的问题&#xff0c;除了依赖于官方更新之外&#xff0c;开发者可以利用《自定义 tabBar》曲线救国 也就是创建一个空内容的自定义tabBar&#xff0c;这样即使 tabBar 被渲染出来&#xff0c;但从视觉上也不会有问题 1.官方文…

24/11/26 视觉笔记 通过特征提取和透视变换查找对象

在本节中我们将检测和跟踪任意大小的对象&#xff0c;这些对象可能是在不同角度或者在部分遮挡的情况下观察到的。 为此我们将运用特征描述子&#xff08;Feature Descriptor&#xff09;&#xff0c;这是捕获感兴趣对象的重要属性的一种方式。我们这样是为了即使将对象嵌入繁…

【单片机毕业设计12-基于stm32c8t6的智能称重系统设计】

【单片机毕业设计12-基于stm32c8t6的智能称重系统设计】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇12-基于stm32c8t6的智能称重系统设计 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功能介绍 ----…

ubuntu中使用ffmpeg和nginx推http hls视频流

视频流除了rtmp、rtsp&#xff0c;还有一种是http的hls流&#xff0c;使用http协议传输hls格式的视频数据。 nginx支持推送hls视频流&#xff0c;使用的是rtmp模块&#xff0c;即rtmp流推送成功了&#xff0c;hls流也没问题。怎么推送rtmp流&#xff0c;请参考我的文章&#x…

5.2.机器学习--岭回归+局部线性回归

目录 1.岭回归 1.1代码示例 2.局部线性回归 2.1代码示例 1.最小二乘法&#xff1a; 平面几何表达直线(两个系数): 重新命名变量: 强行加一个x01&#xff1a; 向量表达&#xff1a; 2.损失函数&#xff1a; 矩阵表达&#xff1a; 矩阵展开&#xff1a; 推导&#xff1a; …

nvidia-container-toolkit安装问题(OpenPGP)

1.正常情况下 apt-get install -y nvidia-container-toolkit2.使用nvidia源 nvidia-container-toolkit官网有安装教程 2.1 配置生产存储库 curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-containe…

电脑上的ip地址可以改吗?如何改变ip地址

在现代网络环境中&#xff0c;IP地址作为设备在网络中的唯一标识&#xff0c;扮演着至关重要的角色。无论是日常上网冲浪&#xff0c;还是进行专业的网络操作&#xff0c;IP地址都与我们息息相关。那么&#xff0c;电脑上的IP地址可以改吗&#xff1f;答案是肯定的。接下来&…

org.apache.log4j的日志记录级别和基础使用Demo

org.apache.log4j的日志记录级别和基础使用Demo&#xff0c;本次案例展示&#xff0c;使用是的maven项目&#xff0c;搭建的一个简单的爬虫案例。里面采用了大家熟悉的日志记录插件&#xff0c;log4j。来自apache公司的开源插件。 package com.qian.test;import org.apache.log…