diff --git a/docs/source/tutorials/misc.rst b/docs/source/tutorials/misc.rst index 4a5e2b907..c4446709b 100644 --- a/docs/source/tutorials/misc.rst +++ b/docs/source/tutorials/misc.rst @@ -118,6 +118,14 @@ However, with multi-threading enabled, it is expected that the results can be no to reset the number of threads to the default. + The thread limit can also be controlled by setting the ``TBB_NUM_THREADS`` environment variable before importing ``ipctk``. This is useful in production environments where you want to enforce a global thread limit without modifying every script that uses the IPC Toolkit: + + .. code-block:: bash + + export TBB_NUM_THREADS=1 + + If set, this takes effect as soon as ``ipctk`` is imported (equivalent to calling ``ipctk.set_num_threads`` with the given value), and can still be overridden later in the script by calling ``ipctk.set_num_threads`` directly. If the variable is unset or invalid, it is ignored and the default thread count is used. + You can also get the current maximum number of threads as follows: .. md-tab-set:: diff --git a/python/src/utils/thread_limiter.cpp b/python/src/utils/thread_limiter.cpp index 859b353f8..d08e76e08 100644 --- a/python/src/utils/thread_limiter.cpp +++ b/python/src/utils/thread_limiter.cpp @@ -41,5 +41,17 @@ void define_thread_limiter(py::module_& m) "set_num_threads", &set_num_threads, "set maximum number of threads to use", "nthreads"_a); + // Allow the thread limit to be set globally via an environment variable + // (e.g., in production) rather than requiring every script to call + // set_num_threads() itself. + const char* env_val = std::getenv("TBB_NUM_THREADS"); + if (env_val != nullptr) { + try { + set_num_threads(std::stoi(env_val)); + } catch (const std::exception& e) { + logger().error("Invalid value for TBB_NUM_THREADS: {}", env_val); + } + } + std::atexit([]() { thread_limiter.reset(); }); }