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(())
}
示例说明
-
这个综合示例展示了:
- 作业对象的创建
- 多种资源限制的设置(内存、进程数、运行时间)
- 安全限制的配置
- 批量进程管理
- 作业信息查询
- 作业终止操作
-
注意事项:
- 需要Windows平台
- 某些操作可能需要管理员权限
- 进程一旦加入作业就无法移除
- 作业对象会自动释放资源
-
实际运行效果:
- 会启动记事本、计算器和画图程序
- 5秒后自动终止所有程序
- 控制台会输出进程信息和作业状态