限制 Rust 程序中的 cpurate

Limit the cpurate in a Rust program

我想限制我是 运行 的 rust 程序的 cpurate。 我在命令中找到了执行此操作的方法,但想知道是否可以使用内置的 rust 模块在程序中执行此操作。

通常,这不是单个程序的问题。最简单和最灵活的方法通常是在 运行 运行程序时设置资源限制(例如通过 Docker 设置)并允许程序只使用给定的资源。

除此之外,让我们假设您确实需要能够做到这一点。在 Linux,您可以使用 cgroups 设置资源限制。

有一些针对 Rust 的 cgroups crate,它们的使用年限和质量各不相同。有些是本机的,有​​些是 C 库的包装器,但其中 none 最近已更新。即便如此,我还是选择了一个在其文档中有示例的 (controlgroup) 并且能够完成这项工作:

use controlgroup::v1::Builder; // controlgroup 0.3.0
use signal_hook:: register; // signal-hook 0.1.16

fn main() {
    set_cpu_percent(10.0);
    
    // Do your work here
}

fn set_cpu_percent(percent: f64) {
    let mut cgroups = Builder::new("my-cgroups".into())
        .cpu()
        .cfs_quota_us((percent * 1000.0) as i64)
        .cfs_period_us(100_000)
        .done()
        .build()
        .unwrap();

    // Add the current task to crgoups
    let pid = std::process::id().into();
    cgroups.add_task(pid).unwrap();

    // Do some clean up, e.g. if you terminate the process with ctrl+C
    unsafe {
        register(signal_hook::SIGINT, {
            // register handler is Fn, so cannot mutate its environment
            let cgroups = std::sync::Mutex::new(cgroups);
            move || {
                let mut cgroups = cgroups.lock().unwrap();
                cgroups.remove_task(pid).unwrap();
                cgroups.delete().unwrap();
                std::process::exit(0);
            }
        })
        .unwrap()
    };
}

请注意,我没有进行任何错误处理,您应该将其视为 proof-of-concept,而不是生产质量代码。我添加 SIGINT 清理处理程序的原因是因为我在第二次 运行 时出错,因为没有清理之前的 运行。我不是该领域的专家,您可能需要考虑许多其他边缘情况才能使其稳健。