linux收集进程性能数据

需求背景:

对内存泄漏进行了修复,通过引流模拟压测,在测试机上收集两个进程的性能数据:cpu、mem、mes_used来对比判断内存泄漏修复的效果

一、收集进程数据

收集数据通过进程名来获取pid

bash 复制代码
get_pid() {
    # 1. 定义局部变量target,接收函数的第一个参数(传入的PID/进程名)
    local target=$1
    # 2. 判断:参数是否是纯数字(即是否是PID)
    if [[ ${target} =~ ^[0-9]+$ ]]; then
        # 2.1 如果是数字,验证该PID对应的进程是否存活
        if ps -p ${target} >/dev/null 2>&1; then
            # 进程存活 → 返回该PID
            echo ${target}
        else
            # 进程不存在 → 返回空字符串
            echo ""
        fi
    # 3. 如果参数不是纯数字(即是进程名/关键词)
    else
        # 3.1 查找包含该关键词的进程,提取第一个PID
        local pid=$(ps -ef | grep -v grep | grep -v $0 | grep ${target} | awk '{print $2}' | head -1)
        # 3.2 返回找到的PID(没找到则返回空)
        echo ${pid}
    fi
}

命令段 作用

ps -ef 列出系统所有进程的完整信息(用户、PID、父 PID、命令等)

grep -v grep 过滤掉 grep 自身进程(避免把 "grep navi-api" 这个临时进程当成目标进程)

grep -v 0 过滤掉当前脚本进程(0是脚本名,避免匹配到脚本自身)

grep ${target} 筛选出包含目标关键词(如 navi-api)的进程

awk '{print $2}' 提取进程信息的第 2 列(即 PID 列)

head -1 只取第一个 PID(避免多个匹配结果时返回多个值)

读取机器的总内存值,用户内存占用率的计算

bash 复制代码
# 读取系统总内存(从/proc/meminfo读取)
get_total_memory_kb() {
    # 1. 核心:读取/proc/meminfo中的MemTotal字段,提取数值(单位KB)
    local total_mem=$(cat /proc/meminfo | grep ^MemTotal: | awk '{print $2}')
    # 2. 容错:如果读取失败/数值为0,用你机器的固定值兜底
    if [[ -z ${total_mem} || ${total_mem} -eq 0 ]]; then
        total_mem=527756124  # 你的机器总内存(KB)
    fi
    # 3. 返回最终的总内存数值
    echo ${total_mem}
}

逐行深度解释

  1. local total_mem=(cat /proc/meminfo \| grep \^MemTotal: \| awk '{print 2}')
    local total_mem:声明局部变量,仅在函数内有效,避免污染全局变量;
    cat /proc/meminfo:读取 Linux 系统的内存信息文件(/proc是内核虚拟文件系统,实时反映系统状态);
    grep ^MemTotal::筛选以MemTotal:开头的行(这一行就是系统总内存,格式如MemTotal: 527756124 kB);
    awk '{print $2}':提取该行的第 2 列(即总内存的数值部分,去掉kB单位);
    最终效果:拿到你服务器的总内存数值(527756124 KB,约 515GB)。
  2. if [[ -z {total_mem} \|\| {total_mem} -eq 0 ]]; then

    \[ -z ${total_mem} \]\]:判断total_mem是否为空(比如/proc/meminfo读取失败、没有找到 MemTotal 行); \[\[ ${total_mem} -eq 0 \]\]:判断数值是否为 0(异常情况); total_mem=527756124:兜底方案 ------ 直接用你机器的固定总内存值,避免后续计算内存使用率时出错(比如除以 0)。

    返回最终的总内存数值,供脚本中计算内存使用率时调用(内存使用率 = 进程已用内存 / 总内存 * 100%)。

collect_process_metrics () 解析(核心:采集单个进程的 CPU / 内存指标)

bash 复制代码
collect_process_metrics() {
    # 1. 接收参数:要采集的进程PID
    local pid=$1
    # 2. 容错:PID为空/进程不存在(/proc/PID文件缺失),直接返回默认值
    if [[ -z ${pid} || ! -f /proc/${pid}/stat || ! -f /proc/${pid}/status ]]; then
        echo "0.00,0.0000,0.00"  # CPU%、内存%、内存MB,统一带小数点
        return  # 退出函数,不再执行后续逻辑
    fi

    # ========== 1. CPU使用率计算(核心:通过/proc/stat和/proc/PID/stat计算) ==========
    # 2.1 读取采集前的系统总CPU时间 + 进程已用CPU时间
    # /proc/stat的cpu行:包含系统启动以来所有CPU的总耗时(单位:jiffies,约1/100秒)
    local cpu_total_prev=$(cat /proc/stat | grep ^cpu | awk '{sum=$2+$3+$4+$5+$6+$7+$8} END {print sum}')
    # /proc/PID/stat的14+15列:进程的用户态+内核态CPU耗时(jiffies)
    local pid_stat_prev=$(cat /proc/${pid}/stat | awk '{print $14+$15}')
    
    # 2.2 等待0.1秒(必须!否则前后两次读取的数值几乎无差异,计算出的CPU使用率为0)
    sleep 0.1
    
    # 2.3 读取采集后的系统总CPU时间 + 进程已用CPU时间
    local cpu_total_curr=$(cat /proc/stat | grep ^cpu | awk '{sum=$2+$3+$4+$5+$6+$7+$8} END {print sum}')
    local pid_stat_curr=$(cat /proc/${pid}/stat | awk '{print $14+$15}')
    
    # 2.4 计算差值:0.1秒内系统总CPU耗时变化量 + 进程CPU耗时变化量
    local cpu_delta=$((cpu_total_curr - cpu_total_prev))  # 系统总耗时增量
    local pid_delta=$((pid_stat_curr - pid_stat_prev))    # 进程耗时增量
    local cpu_usage=0.00  # 初始化CPU使用率
    
    # 2.5 计算CPU使用率(避免除以0)
    if [[ ${cpu_delta} -gt 0 ]]; then
        # scale=2:保留2位小数;公式:(进程耗时增量/系统总耗时增量)*100%
        cpu_usage=$(echo "scale=2; ${pid_delta}/${cpu_delta}*100" | bc)
    fi

    # ========== 2. 内存指标计算(核心:读取/proc/PID/status的VmRSS) ==========
    # 2.1 读取进程已用物理内存(VmRSS,单位:KB)
    local mem_rss=$(cat /proc/${pid}/status | grep ^VmRSS: | awk '{print $2}')
    if [[ -z ${mem_rss} ]]; then  # 容错:读取失败则设为0
        mem_rss=0
    fi
    
    # 2.2 获取系统总内存(KB)(调用之前的get_total_memory_kb函数)
    local total_mem_kb=$(get_total_memory_kb)
    
    # 2.3 计算内存使用量(MB):KB转MB,保留2位小数
    local mem_mb=$(echo "scale=2; ${mem_rss}/1024" | bc)
    
    # 2.4 计算内存使用率(%):保留4位小数,避免显示为0
    local mem_usage=0.0000
    if [[ ${total_mem_kb} -gt 0 && ${mem_rss} -gt 0 ]]; then
        mem_usage=$(echo "scale=4; (${mem_rss}/${total_mem_kb})*100" | bc)
    fi

    # ========== 3. 格式化数值(适配gnuplot,补前导0/小数点) ==========
    cpu_usage=$(format_number "${cpu_usage}")
    mem_usage=$(format_number "${mem_usage}")
    mem_mb=$(format_number "${mem_mb}")

    # ========== 4. 返回结果(CSV格式:CPU%,内存%,内存MB) ==========
    echo "${cpu_usage},${mem_usage},${mem_mb}"
}

关键知识点(CPU / 内存计算原理)

  1. CPU 使用率为什么要算 "差值"?
    /proc/stat 和 /proc/PID/stat 存储的是从系统启动到现在的累计耗时(不是实时使用率);
    只有计算 "0.1 秒内的增量比值",才能得到这 0.1 秒内的实时 CPU 使用率;
    sleep 0.1 是核心:如果不等待,前后两次读取的数值几乎一样,差值为 0,CPU 使用率就会是 0(这也是你之前部分行 CPU 为 0 的原因之一)。
  2. 内存指标的核心字段:VmRSS
    VmRSS(Resident Set Size):进程实际占用的物理内存(KB),是最能反映进程内存使用的指标;
    内存使用率公式:(进程VmRSS / 系统总内存) * 100%(你的服务器总内存大,所以使用率低,约 0.1%);
    内存 MB 公式:VmRSS / 1024(KB 转 MB,更易理解)。
  3. 容错设计
    PID 为空 / 进程不存在 → 返回默认值 0.00,0.0000,0.00,避免脚本崩溃;
    内存读取失败 → 设为 0,避免后续计算出错;
    CPU 差值为 0 → 使用率设为 0,避免除以 0 报错。

collect_data () 解析(核心:循环采集 + 写入 CSV)

bash 复制代码
collect_data() {
    # 1. 计算监控结束时间:开始时间(秒级时间戳) + 监控时长(秒)
    local start_time=$(date +%s)  # 当前时间戳(如1742200000)
    local end_time=$((start_time + MONITOR_DURATION))  # 结束时间戳
    echo "开始监控(开始时间:$(date +%Y-%m-%d\ %H:%M:%S))..."
    
    # 2. 循环采集:只要当前时间 < 结束时间,就一直采集
    while [[ $(date +%s) -lt ${end_time} ]]; do
        # 2.1 获取当前时间戳(格式化,写入CSV)
        local timestamp=$(date +%Y-%m-%d\ %H:%M:%S)  # 如2026-03-17 12:53:42
        
        # 2.2 获取两个进程的PID(调用之前的get_pid函数)
        local pid1=$(get_pid ${PROCESS_NAME_1})  # 8078的PID
        local pid2=$(get_pid ${PROCESS_NAME_2})  # 8079的PID
        
        # 2.3 采集两个进程的指标(调用collect_process_metrics)
        local metrics1=$(collect_process_metrics ${pid1})  # 8078的CPU%,内存%,内存MB
        local metrics2=$(collect_process_metrics ${pid2})  # 8079的CPU%,内存%,内存MB
        
        # 2.4 拼接数据并写入CSV
        # 格式:时间戳,进程1CPU%,进程1内存%,进程1内存MB,进程2CPU%,进程2内存%,进程2内存MB
        echo "${timestamp},${metrics1},${metrics2}" >> ${DATA_FILE}
        # 终端打印日志(方便查看实时采集情况)
        echo "[$timestamp] P1:${metrics1} | P2:${metrics2}"
        
        # 2.5 等待采集间隔(如60秒),避免高频采集
        sleep ${COLLECT_INTERVAL}
    done
    
    echo "监控结束(结束时间:$(date +%Y-%m-%d\ %H:%M:%S))"
}

容错:

物理机的内存会比较大,内存利用率会小于0,会导致图表展示失败,gnuplot 对数值格式要求严格:

纯整数(如0)、缺少前导 0 的小数(如.1100)会被识别为 "非有效数值",导致图表为空 / 只显示部分曲线;

这个函数的唯一目的:把所有数值统一成 gnuplot 能识别的格式。

bash 复制代码
# 格式化数值(补前导0,确保gnuplot能识别)
format_number() {
    local num=$1  # 接收传入的数值参数(如0、.1100、9.00)
    # 情况1:纯整数(如0、9、50)→ 补小数点后两位(0→0.00,9→9.00)
    if [[ ${num} =~ ^[0-9]+$ ]]; then
        echo "${num}.00"
    # 情况2:以小数点开头(如.1100、.0800)→ 补前导0(.1100→0.1100)
    elif [[ ${num} =~ ^\.[0-9]+$ ]]; then
        echo "0${num}"
    # 情况3:正常格式(如9.00、0.1100)→ 保持不变
    else
        echo "${num}"
    fi
}

二、将收集的数据,按照图表的形式展示

工具:gnuplot

安装:root权限

python 复制代码
yum install-y gnuplot

校验安装是否成功

bash 复制代码
gnuplot --version

gnuplog介绍

Gnuplot 是一款跨平台、开源免费的命令行绘图工具,核心用途是将数值数据(如你的进程监控 CSV)转换为可视化图表(PNG/JPG/PDF 等),尤其适合 Linux 服务器环境下的自动化图表生成(比如你用的进程 CPU / 内存监控)。

例如生成图片的命令如下

bash 复制代码
gnuplot -e "
    # 1. 定义输出终端(图表格式/尺寸/增强模式)
    set terminal png size 1200,800 enhanced;
    # 2. 指定图表保存路径
    set output '${CHART_DIR}/cpu_comparison.png';
    # 3. 设置图表标题(明确对比的两个进程)
    set title 'Process CPU Usage Comparison (navi-api-luciazhaolu-8078 vs 8079)';
    # 4. 设置X轴标签
    set xlabel 'Time';
    # 5. 设置Y轴标签(标注单位)
    set ylabel 'CPU Usage (%)';
    # 6. 显示网格(方便读取数值)
    set grid;
    # 7. 定义时间解析格式(匹配CSV中的时间戳)
    set timefmt '%Y-%m-%d %H:%M:%S';
    # 8. 声明X轴为时间类型(而非普通数值)
    set xdata time;
    # 9. 设置X轴时间显示格式(简化显示,避免拥挤)
    set format x '%m-%d %H:%M';
    # 10. X轴标签旋转45度(防止时间戳重叠)
    set xtics rotate by 45;
    # 11. 指定数据分隔符(CSV用逗号分隔)
    set datafile separator ',';
    # 12. 核心绘图命令(画两条曲线)
    plot '${CSV_FILE}' using 1:2 title 'navi-api-luciazhaolu-8078' with lines lw 2 lc rgb '#1E90FF', \
         '${CSV_FILE}' using 1:5 title 'navi-api-luciazhaolu-8079' with lines lw 2 lc rgb '#FF6347';
"

关键要点:

set terminal/set output 决定图表 "长什么样、存在哪";

set xdata time/set timefmt 解决时间轴解析问题;

set datafile separator ',' 确保 CSV 列解析正确;

plot using 1:2/1:5 选择要可视化的核心数据列(进程 1/2 的 CPU 使用率)

三、整体代码

bash 复制代码
#!/bin/bash
set -e

# ====================== 配置项(根据需求修改)======================
PROCESS_NAME_1="navi-api-luciazhaolu-8078"       # navi-api-luciazhaolu-8078
PROCESS_NAME_2="navi-api-luciazhaolu-8079"       # navi-api-luciazhaolu-8079
MONITOR_DURATION=600        # 监控时长(秒)
COLLECT_INTERVAL=60         # 采集间隔(秒)
DATA_DIR="/home/xiaoju/qa/zhaolu/process_monitor_data"
CHART_DIR="/home/xiaoju/qa/zhaolu/process_monitor_charts"
# ==================================================================

# 初始化目录
init_dir() {
    mkdir -p ${DATA_DIR}
    mkdir -p ${CHART_DIR}
    DATA_FILE="${DATA_DIR}/process_metrics_$(date +%Y%m%d_%H%M%S).csv"
    # 写入CSV表头
    echo "timestamp,process1_cpu%,process1_mem%,process1_mem_mb,process2_cpu%,process2_mem%,process2_mem_mb" > ${DATA_FILE}
    echo "初始化完成,数据文件:${DATA_FILE}"
    echo "监控时长:10分钟(${MONITOR_DURATION}秒),采集间隔:${COLLECT_INTERVAL}秒"
}

# 获取进程PID
get_pid() {
    local target=$1
    if [[ ${target} =~ ^[0-9]+$ ]]; then
        if ps -p ${target} >/dev/null 2>&1; then
            echo ${target}
        else
            echo ""
        fi
    else
        local pid=$(ps -ef | grep -v grep | grep -v $0 | grep ${target} | awk '{print $2}' | head -1)
        echo ${pid}
    fi
}

# 读取系统总内存(从/proc/meminfo读取)
get_total_memory_kb() {
    local total_mem=$(cat /proc/meminfo | grep ^MemTotal: | awk '{print $2}')
    if [[ -z ${total_mem} || ${total_mem} -eq 0 ]]; then
        total_mem=527756124  # 你的机器总内存
    fi
    echo ${total_mem}
}

# 格式化数值(补前导0,确保gnuplot能识别)
format_number() {
    local num=$1
    # 如果是纯整数,补小数点后两位
    if [[ ${num} =~ ^[0-9]+$ ]]; then
        echo "${num}.00"
    # 如果是.xxx格式,补前导0
    elif [[ ${num} =~ ^\.[0-9]+$ ]]; then
        echo "0${num}"
    # 其他情况保持不变
    else
        echo "${num}"
    fi
}

# 采集单个进程的CPU/内存指标
collect_process_metrics() {
    local pid=$1
    if [[ -z ${pid} || ! -f /proc/${pid}/stat || ! -f /proc/${pid}/status ]]; then
        echo "0.00,0.0000,0.00"  # 统一格式为带小数点的数值
        return
    fi

    # 1. CPU使用率计算
    local cpu_total_prev=$(cat /proc/stat | grep ^cpu | awk '{sum=$2+$3+$4+$5+$6+$7+$8} END {print sum}')
    local pid_stat_prev=$(cat /proc/${pid}/stat | awk '{print $14+$15}')
    sleep 0.1
    local cpu_total_curr=$(cat /proc/stat | grep ^cpu | awk '{sum=$2+$3+$4+$5+$6+$7+$8} END {print sum}')
    local pid_stat_curr=$(cat /proc/${pid}/stat | awk '{print $14+$15}')
    
    local cpu_delta=$((cpu_total_curr - cpu_total_prev))
    local pid_delta=$((pid_stat_curr - pid_stat_prev))
    local cpu_usage=0.00
    if [[ ${cpu_delta} -gt 0 ]]; then
        cpu_usage=$(echo "scale=2; ${pid_delta}/${cpu_delta}*100" | bc)
    fi

    # 2. 内存指标计算
    local mem_rss=$(cat /proc/${pid}/status | grep ^VmRSS: | awk '{print $2}')
    if [[ -z ${mem_rss} ]]; then
        mem_rss=0
    fi
    local total_mem_kb=$(get_total_memory_kb)
    local mem_mb=$(echo "scale=2; ${mem_rss}/1024" | bc)
    local mem_usage=0.0000
    if [[ ${total_mem_kb} -gt 0 && ${mem_rss} -gt 0 ]]; then
        mem_usage=$(echo "scale=4; (${mem_rss}/${total_mem_kb})*100" | bc)
    fi

    # 格式化数值(确保带小数点)
    cpu_usage=$(format_number "${cpu_usage}")
    mem_usage=$(format_number "${mem_usage}")
    mem_mb=$(format_number "${mem_mb}")

    echo "${cpu_usage},${mem_usage},${mem_mb}"
}

# 主采集逻辑
collect_data() {
    local start_time=$(date +%s)
    local end_time=$((start_time + MONITOR_DURATION))
    echo "开始监控(开始时间:$(date +%Y-%m-%d\ %H:%M:%S))..."
    
    while [[ $(date +%s) -lt ${end_time} ]]; do
        local timestamp=$(date +%Y-%m-%d\ %H:%M:%S)
        local pid1=$(get_pid ${PROCESS_NAME_1})
        local pid2=$(get_pid ${PROCESS_NAME_2})
        
        local metrics1=$(collect_process_metrics ${pid1})
        local metrics2=$(collect_process_metrics ${pid2})
        
        # 拼接并写入CSV
        echo "${timestamp},${metrics1},${metrics2}" >> ${DATA_FILE}
        echo "[$timestamp] P1:${metrics1} | P2:${metrics2}"
        
        sleep ${COLLECT_INTERVAL}
    done
    
    echo "监控结束(结束时间:$(date +%Y-%m-%d\ %H:%M:%S))"
}

# 生成可视化图表(增加容错,确保所有图表都能生成)
generate_charts() {
    echo "开始生成可视化图表..."
    local cpu_chart="${CHART_DIR}/cpu_comparison.png"
    local mem_chart="${CHART_DIR}/mem_comparison.png"
    local mem_mb_chart="${CHART_DIR}/mem_mb_comparison.png"

    # 生成CPU对比图(修复数据解析问题)
    gnuplot -e "
        set terminal png size 1200,800 enhanced;
        set output '${cpu_chart}';
        set title 'Process CPU Usage Comparison (navi-api-luciazhaolu-8078 vs 8079)';
        set xlabel 'Time';
        set ylabel 'CPU Usage (%)';
        set grid;
        set timefmt '%Y-%m-%d %H:%M:%S';
        set xdata time;
        set format x '%m-%d %H:%M';
        set xtics rotate by 45;
        set datafile separator ',';  # 明确指定分隔符
        plot '${DATA_FILE}' using 1:2 title 'navi-api-luciazhaolu-8078' with lines lw 2 lc rgb '#1E90FF', \
             '${DATA_FILE}' using 1:5 title 'navi-api-luciazhaolu-8079' with lines lw 2 lc rgb '#FF6347';
    " || echo "CPU图表生成警告(继续生成其他图表)"

    # 生成内存使用率对比图(修复空图问题)
    gnuplot -e "
        set terminal png size 1200,800 enhanced;
        set output '${mem_chart}';
        set title 'Process Memory Usage (%) Comparison (navi-api-luciazhaolu-8078 vs 8079)';
        set xlabel 'Time';
        set ylabel 'Memory Usage (%)';
        set grid;
        set timefmt '%Y-%m-%d %H:%M:%S';
        set xdata time;
        set format x '%m-%d %H:%M';
        set xtics rotate by 45;
        set datafile separator ',';  # 明确指定分隔符
        plot '${DATA_FILE}' using 1:3 title 'navi-api-luciazhaolu-8078' with lines lw 2 lc rgb '#1E90FF', \
             '${DATA_FILE}' using 1:6 title 'navi-api-luciazhaolu-8079' with lines lw 2 lc rgb '#FF6347';
    " || echo "内存使用率图表生成警告(继续生成其他图表)"

    # 生成内存使用量(MB)对比图(确保生成)
    gnuplot -e "
        set terminal png size 1200,800 enhanced;
        set output '${mem_mb_chart}';
        set title 'Process Memory Usage (MB) Comparison (navi-api-luciazhaolu-8078 vs 8079)';
        set xlabel 'Time';
        set ylabel 'Memory Usage (MB)';
        set grid;
        set timefmt '%Y-%m-%d %H:%M:%S';
        set xdata time;
        set format x '%m-%d %H:%M';
        set xtics rotate by 45;
        set datafile separator ',';  # 明确指定分隔符
        plot '${DATA_FILE}' using 1:4 title 'navi-api-luciazhaolu-8078' with lines lw 2 lc rgb '#1E90FF', \
             '${DATA_FILE}' using 1:7 title 'navi-api-luciazhaolu-8079' with lines lw 2 lc rgb '#FF6347';
    " || echo "内存使用量图表生成警告"

    echo "图表生成完成:"
    echo "  CPU对比图:${cpu_chart}"
    echo "  内存使用率对比图:${mem_chart}"
    echo "  内存使用量对比图:${mem_mb_chart}"
}

# 检查依赖
check_dependencies() {
    local dependencies=("bc" "gnuplot" "ps" "cat")
    for dep in ${dependencies[@]}; do
        if ! command -v ${dep} &> /dev/null; then
            echo "错误:缺少依赖 ${dep},请先安装!"
            exit 1
        fi
    done
}

# 兼容已有CSV文件(修复格式问题,无需重跑监控)
fix_existing_csv() {
    local csv_file=$1
    if [[ ! -f ${csv_file} ]]; then
        echo "CSV文件不存在:${csv_file}"
        return 1
    fi
    # 创建临时文件
    local tmp_file=$(mktemp)
    # 保留表头,修复数据行格式
    head -1 ${csv_file} > ${tmp_file}
    tail -n +2 ${csv_file} | while read line; do
        # 拆分列
        IFS=',' read -r ts cpu1 mem1 mb1 cpu2 mem2 mb2 <<< "${line}"
        # 格式化每一列数值
        cpu1=$(format_number "${cpu1}")
        mem1=$(format_number "${mem1}")
        mb1=$(format_number "${mb1}")
        cpu2=$(format_number "${cpu2}")
        mem2=$(format_number "${mem2}")
        mb2=$(format_number "${mb2}")
        # 写入临时文件
        echo "${ts},${cpu1},${mem1},${mb1},${cpu2},${mem2},${mb2}" >> ${tmp_file}
    done
    # 替换原文件
    mv ${tmp_file} ${csv_file}
    echo "已修复CSV文件格式:${csv_file}"
}

# 主流程
main() {
    check_dependencies
    init_dir
    collect_data
    generate_charts
    echo "==================== 监控完成 ===================="
    echo "数据文件路径:${DATA_FILE}"
    echo "图表目录:${CHART_DIR}"
}

# 如果你想修复已有CSV文件并重新生成图表,执行:
# fix_existing_csv "/home/xiaoju/qa/zhaolu/process_monitor_data/process_metrics_20260317_125342.csv"
# 然后手动执行generate_charts函数(替换DATA_FILE为你的文件路径)

# 启动主流程
main
相关推荐
Byte不洛2 小时前
手写一个C++ TCP服务器实现自定义协议(顺便解决粘包问题)
linux·c++·操作系统·网络编程·tcp
amcomputer2 小时前
服务器数据如何实现备份同步?
运维·服务器
Cc琎2 小时前
api接口分布在多台服务器, 如何同步用户的每日请求次数
java·运维·服务器·redis·php
小码吃趴菜2 小时前
服务器预约系统linux小项目-第一节课
运维·服务器
搬山境KL攻城狮3 小时前
ssh密钥对使用
运维·ssh
道亦无名4 小时前
Linux下是STM32的编译修改配置文件tensorflow
linux·运维
Azure DevOps4 小时前
Azure DevOps Server:2026年3月份补丁
运维·microsoft·azure·devops
wanhengidc10 小时前
云手机的运行环境如何
运维·服务器·游戏·智能手机·生活
炸膛坦客10 小时前
Linux - Ubuntu - PC端:(三)切换中英文,Fcitx5
linux·ubuntu