Add the ability to specify the number of threads for a component when using component_container_isolated
Description
Allow users to specify the amount of threads used by individual components when using isolated component container. This would prevent the unnecessary creation and usage of threads that is not the default behaviour.
Motivation
Currently, there is no option to specify the number of threads to use on the component level like with standalone nodes:
auto executor = rclcpp::executors::MultiThreadedExecutor(rclcpp::ExecutorOptions(), 3);
This leads to the situation where the default constructor for MultiThreadedExecutor is called without without arguments ( the template parameter resolves here) and the created Executor creates the maximum amount of threads by default. Most of the uses cases I have seen do not need that many threads.
Design / Implementation Considerations
The nodes may be loaded to the container by calling the /load_node service. To my understanding, this is what the LoadComposableNodes launch action does. The service definition contains parameters and extra_parameters fields which may be filled to node options. The component manager could then see if the parameter thread_num is specified for the node and pass it to the add_node_to_executor call where it would be passed to MultiThreadedExecutor constructor.
Additional Information
I understand that this is quite a niche issue and might not be worth the implementation effort. Feel free to close this issue if it is not relevant.
Hi @elmeripk. On our weekly ROS 2 triage meeting, we discussed this issue/proposal and came to the conclusion that we agree that this is a good-to-have proposal. However, community help with implementation is wanted here.
This issue has been mentioned on Open Robotics Discourse. There might be relevant details there:
https://discourse.openrobotics.org/t/ros-news-for-the-week-of-august-11th-2025/49591/1
i would suggest this feature with a bit of refactoring instead,
- probably we should only keep
component_container, and deprecate all the other container executable such ascomponent_container_isolated,component_container_mtandcomponent_container_event. - for container node, we can use
Parametersto load which executor type should be used. for example,ros2 run rclcpp_components component_container --ros-args -p executor_type:=multi_threadto useMultiThreadedExecutorfor the container node itself. maybe we can also have a few more extra parameters such as how many threads are used for theMultiThreadedExecutor. - for the components, we can set how we want to configure the executor for the node via composition_interfaces/srv/LoadNode. for example, we want to allocate the dedicated
SingleThreadedExecutorfor the component, we want to share the executor with component container, or we want to allocate the dedicatedMultiThreadedExecutorwith specific number of threads.
i believe with this design,
- we can have better granularity to configure the executor type for container node and each components when they are loaded to the container.
- simple user experience via ros2 parameter interfaces.
- we probably can get rid of the redundant codes between component containers and CMake files.
Is someone working on this? I am interested in this feature!!
AFAIK, nobody is working on this right now. if you consider the contribution, that would be really appreciated.
@fujitatomoya
I was thinking about this feature and the proposed design, and I want to try implementing it. I just want to make sure that I understand the proposed design correctly before starting my work.
for the components, we can set how we want to configure the executor for the node via composition_interfaces/srv/LoadNode. for example, we want to allocate the dedicated SingleThreadedExecutor for the component, we want to share the executor with component container, or we want to allocate the dedicated MultiThreadedExecutor with specific number of threads.
So, by doing this, we not only deprecate the three container executables mentioned in the proposed design, but also the ComponentManagerIsolated itself, and we handle the case of creating a dedicated executor for a new node inside the add_node_to_executor method of ComponentManager, right?