Rust Windows作业管理库win32job的使用:实现进程组控制和资源限制的Win32 API封装

Rust Windows作业管理库win32job的使用:实现进程组控制和资源限制的Win32 API封装

win32job是一个安全的Windows作业对象API封装库,可用于设置与作业对象关联进程的各种限制。

安装

在Cargo.toml中添加依赖:

[dependencies]
win32job = "2"

示例

限制进程可用内存

限制当前进程可用工作内存为1MB到4MB:

use win32job::{Job, ExtendedLimitInfo};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut info = ExtendedLimitInfo::new();

    info.limit_working_memory(1 * 1024 * 1024, 4 * 1024 * 1024);

    let job = Job::create_with_limit_info(&mut info)?;

    job.assign_current_process()?;
    
    Ok(())
}

主进程退出时强制终止子进程

创建作业对象并设置当主进程退出时自动终止所有子进程:

use win32job::Job;
use std::process::Command;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let job = Job::create()?;
    
    let mut info = job.query_extended_limit_info()?;

    info.limit_kill_on_job_close();

    job.set_extended_limit_info(&mut info)?;
    
    job.assign_current_process()?;

    Command::new("cmd.exe")
            .arg("/C")
            .arg("ping -n 9999 127.0.0.1")
            .spawn()?;

    // cmd进程将在主进程退出或job对象被丢弃时被终止
    
    Ok(())
}

完整示例代码

下面是一个更完整的示例,展示了如何创建作业对象、设置资源限制并管理进程组:

use win32job::{Job, ExtendedLimitInfo};
use std::process::Command;
use std::thread;
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建作业对象
    let job = Job::create()?;
    
    // 设置作业限制信息
    let mut info = ExtendedLimitInfo::new();
    
    // 设置内存限制:最小1MB,最大4MB
    info.limit_working_memory(1 * 1024 * 1024, 4 * 1024 * 1024);
    
    // 设置主进程退出时自动终止子进程
    info.limit_kill_on_job_close();
    
    // 设置CPU时间限制:最多允许运行10秒
    info.limit_cpu_time(Duration::from_secs(10));
    
    // 应用限制设置
    job.set_extended_limit_info(&mut info)?;
    
    // 将当前进程分配到作业对象
    job.assign_current_process()?;

    // 创建子进程
    let child = Command::new("cmd.exe")
        .arg("/C")
        .arg("ping -t 127.0.0.1")  // 持续ping
        .spawn()?;

    println!("子进程已创建,PID: {}", child.id());
    
    // 主进程等待5秒
    thread::sleep(Duration::from_secs(5));
    
    println!("主进程即将退出,子进程将被自动终止");
    
    Ok(())
}

许可证

win32job库采用以下许可证之一:

Apache License, Version 2.0
MIT license

可根据需要选择使用。


1 回复

以下是基于您提供的内容整理的完整示例demo,先展示内容中的示例,然后提供一个综合示例:

内容中提供的示例回顾

基本示例

use std::process::Command;
use win32job::{Job, JobObject, Limit};

fn main() -> std::io::Result<()> {
    let job = JobObject::create()?;
    let mut limits = Job::new();
    limits.set_limit(Limit::JobMemory(10 * 1024 * 1024));
    job.set_limits(&limits)?;
    
    let mut child = Command::new("notepad.exe")
        .creation_flags(winapi::um::winbase::CREATE_BREAKAWAY_FROM_JOB)
        .spawn()?;
    
    job.assign_process(child.id())?;
    child.wait()?;
    Ok(())
}

设置多个限制

let mut limits = Job::new();
limits.set_limit(Limit::ActiveProcess(5));
limits.set_limit(Limit::JobTime(1000));
limits.set_limit(Limit::ProcessTime(500));
limits.set_limit(Limit::WorkingSetSize(50 * 1024 * 1024));
job.set_limits(&limits)?;

完整综合示例

use std::process::Command;
use win32job::{Job, JobObject, Limit};
use winapi::um::winnt::JOB_OBJECT_SECURITY_NO_ADMIN;

fn main() -> std::io::Result<()> {
    // 1. 创建作业对象
    let job = JobObject::create()?;
    
    // 2. 设置作业限制
    let mut limits = Job::new();
    // 内存限制:20MB
    limits.set_limit(Limit::JobMemory(20 * 1024 * 1024));
    // 最多允许3个进程
    limits.set_limit(Limit::ActiveProcess(3));
    // 作业总运行时间限制:2秒
    limits.set_limit(Limit::JobTime(2000));
    // 安全限制:不需要管理员权限
    limits.set_security_limit(JOB_OBJECT_SECURITY_NO_ADMIN);
    
    // 应用限制到作业对象
    job.set_limits(&limits)?;
    
    // 3. 创建并管理多个进程
    let processes = ["notepad.exe", "calc.exe", "mspaint.exe"];
    
    for &process in &processes {
        let mut child = Command::new(process)
            .creation_flags(winapi::um::winbase::CREATE_BREAKAWAY_FROM_JOB)
            .spawn()?;
            
        // 将进程分配到作业中
        job.assign_process(child.id())?;
        
        // 简单打印进程ID
        println!("Started {} with PID: {}", process, child.id());
    }
    
    // 4. 查询作业信息
    let info = job.query_basic_info()?;
    println!("当前作业中的进程数: {}", info.active_processes);
    
    // 5. 等待5秒后终止所有进程
    std::thread::sleep(std::time::Duration::from_secs(5));
    job.terminate(0)?;
    println!("已终止作业中的所有进程");
    
    Ok(())
}

示例说明

  1. 这个综合示例展示了:

    • 作业对象的创建
    • 多种资源限制的设置(内存、进程数、运行时间)
    • 安全限制的配置
    • 批量进程管理
    • 作业信息查询
    • 作业终止操作
  2. 注意事项:

    • 需要Windows平台
    • 某些操作可能需要管理员权限
    • 进程一旦加入作业就无法移除
    • 作业对象会自动释放资源
  3. 实际运行效果:

    • 会启动记事本、计算器和画图程序
    • 5秒后自动终止所有程序
    • 控制台会输出进程信息和作业状态
回到顶部