限制 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
清理处理程序的原因是因为我在第二次 运行 时出错,因为没有清理之前的 运行。我不是该领域的专家,您可能需要考虑许多其他边缘情况才能使其稳健。
我想限制我是 运行 的 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
清理处理程序的原因是因为我在第二次 运行 时出错,因为没有清理之前的 运行。我不是该领域的专家,您可能需要考虑许多其他边缘情况才能使其稳健。