-
Notifications
You must be signed in to change notification settings - Fork 341
Added support for configuring number of threads, and thread name, used by POOL in task::executor #690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks for PR! I don't know why it is necessary. I can't decide to merge this feature. Any opinions on incorporating this feature? |
@k-nasa thanks for taking a look at this. This PR by no means is meant to be the definitive implementation for supporting a Runtime's configuration. I wanted to added support for configuring the number of threads without altering the current design. From reading the issues it appears that a bigger re-design will be coming. As to your comment "I don't know why it is necessary": it is often essential to have finer grained control of the resources a program utilizes. It is not uncommon for processes to be given cpu affinity, whether it be a program written in rust or another process running on the same server. These types of configurations will be necessary for some. Thanks again |
… as well as thread name, used by POOL in task::executor
ping @yoshuawuyts @stjepang |
@mward thanks for opening this issue! We've been talking about how to configure threadpool sizes in the past, and the best method for that right now seems to be to follow Rayon's lead and read it from env vars if set. That allows sysadmins to change the limits without requiring it to be recompiled. This patch is a bit different: it introduces new types inside the program to set these limits. We agree this could be useful, but we'd like to see global limits through env vars be possible first. |
As we take great care to not expose any runtime details to users through the async-std interface, I'd not use such an interface. A runtime-specific number of ENV vars makes sense, through. |
I found this issue when I try to find a way to limit the number of threads used in async_std. Has this ENV var been implemented? I cannot find any relevant information in the documentation. |
Also on a system with huge (think 64+) number of cores, heavy parallel running of a small (consider something like logger(1) implemented in rust) binary will be kinda inefficient, since your program makes two or three "logical" syscalls (like reading from /etc/passwd, opening /dev/log and writing to it), but before it runs 64+ heavy clone() calls that it will not utilize anyway. |
Also there is another problem: the PID number is limited to 32k by default on Linux and BSD. So on a system with large number of CPUs it will take less than 1024 processes (e.g. 256 on modern Epycs that have 128 processors when HT enabled) to fill up the PID space entirely. And since privsep model is finally getting popular the actual number of running programs may be lower. And in most cases people really don't need that much threads. |
Any update on this? I'd like to set the number of threads and CPU affinity so that my 3D printer's web server runs on Edit: Just seeing cpu affinity is inherited by forked processes so really there's no changes to async-std for CPU affinity needed beyond this PR if I call |
This change requires either system administrator or a user to know what's going on. Or requires a programmer to create a wrapper around the program. |
@heroin-moose in this comparatively uncommon situation, you can also set the env from within rust if you really need to: fn main() {
std::env::set_var("ASYNC_STD_THREAD_COUNT", "3");
std::env::set_var("ASYNC_STD_THREAD_NAME", "my-app-threads");
async_std::task::block_on(async {
//
});
} |
@jbr Yes that worked for me, thanks for the quick reply! Full example from my code in case anyone else stumbles across this in future trying to do something similar: fn main() -> Result<()> {
use nix::sched::{CpuSet, sched_setaffinity};
use nix::unistd::Pid;
let logical_cpus = num_cpus::get();
// Restrict the server to any logical CPU except for the one that is reserved for
// the printer driver processes (eg. teg-marlin).
let mut cpu_set = CpuSet::new();
for cpu_index in 1..logical_cpus {
cpu_set.set(cpu_index)?;
}
sched_setaffinity(Pid::from_raw(0), &cpu_set)?;
// Run one async-std thread for each logical CPU except for the one that is reserved for
// the printer driver processes (eg. teg-marlin).
let threads = std::cmp::max(logical_cpus.saturating_sub(1), 1);
std::env::set_var("ASYNC_STD_THREAD_COUNT", threads.to_string());
// Start the runtime
async_std::task::block_on(app())
} |
This update allows user of this library to, optionally, configure the number of threads, and thread names, used by
task::executor::pool::POOL
.example: