Rosanswers logo


I was wondering if there are any best practices for implementing multiple ROS2 nodes in the same process.

So far I see the following options:

  • std::thread / pthread
  • SingleThreadedExecutor
  • MultiThreadedExecutor
  • composition API

From my understanding of the topic, the composition API should be used whenever we want to define which nodes to use at runtime.

On the other hand, all the other methods require the nodes to be specified at compile time.

I'm currently using mainly std::thread or pthread, as they integrate nicely with other non-ROS code. However I'm also trying to make some experiments about the performance of the ROS executors, to see how they compare with simply spawning a new thread for each node I have.

I noticed that all the examples in the ROS2 tutorial use the executors, what's their advantage?


Originally posted by alsora on ROS Answers with karma: 1322 on 2018-12-05

Post score: 5


1 Answer 1


Rosanswers logo

Composition just means that you provide the node (as a class that inherits from node) and someone else (like a boilerplate main function or composition executable) provide the threading with an executor of some sort.

Composition uses executors to execute one or more nodes in a thread (in the case of SingleThreadedExecutor) or in multiple threads (in the case of MultiThreadedExecutor).

The single threaded executor just runs in the thread in which you call executor.spin().

The multi threaded executor creates threads using std::thread and then dispatches work to them from the thread in which you call executor.spin().

So if you use the composition demo (https://github.com/ros2/demos/tree/master/composition) then it will most likely be using a single threaded executor in the main thread, e.g.:


But there's no reason for that really, another composition example might use a multi threaded executor or a single threaded executor in a thread created with pthread.

In fact, if you used a multi threaded executor to load one or more component nodes (again nodes implemented as a sub class of rclcpp::Node), then you're using most of the things you listed: composition, MultiThreadedExecutor, std::thread, and pthread (because std::thread is probably implemented with pthread on your machine).

I'll also mention that the single and multi threaded executor are just the two built in executors, but you can create your own if you'd like to do something different with the creation of threads, or scheduling of callbacks, or the distribution of callbacks to certain threads, etc...

My recommendation is put all of your "business logic" for your node in one set of source files and implement it as a sub class of rclcpp::Node, but avoid creating any executors or calling spin anywhere. And in a separate file, you can have one of these "boilerplate main" functions which creates an executor, creates an instance of your node, adds your node to the executor, and then calls spin().

Then in the future you'll easily be able to take advantage of composition because the only thing anyone needs to do in order to compose your node into a process is instantiate it and add it to an executor.

Originally posted by William with karma: 17335 on 2018-12-05

This answer was ACCEPTED on the original site

Post score: 7

Original comments

Comment by alsora on 2018-12-06:
Thank you for the detailed answer! Actually, talking about composition, I was referring to https://github.com/ros2/demos/blob/master/composition/src/api_composition.cpp where the LoadNode service is used.

Comment by William on 2018-12-06:
That works for any node that is setup like the talker and listener examples in the demo, specifically: your node is a subclass of rclcpp::Node, you register it in your C++ (CLASS_LOADER_REGISTER_CLASS(composition::Talker, rclcpp::Node)), and you register it in cmake.

Comment by William on 2018-12-06:
I will say there's ongoing work to make this process easier and simpler, and to provide more out-of-the-box component containers and to integrate it with launch, watch for progress: https://github.com/ros2/launch/issues/101 (maybe a different issue in the future)

Comment by aby on 2020-04-09:
@alsora the link is dead.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.