Rosanswers logo

To put it simply: What is the application of multithreading in ros nodes?

I am not from a Computer Science background. I have been learning Operating System concepts like processes, threads, signals, etc., only very recently. I came to the conclusion that one would hardly have to use a fork() in a ROS program because ROS nodes are themselves like different processes. (Ques.1) Is this conclusion right? Or, are the instances where one might need to use the fork() and exec()?

I got the idea of using a one thread to simply wait for callbacks all the time and another to do the useful work, from here.

(Ques.2) Is this the standard way of doing it? Is it a good idea to follow the idea quoted above or is it better to include a ros::spinOnce() regularly in the code? The latter sounds a buggy solution to me. Please correct me where I am wrong.

If I do as it has been shown in that tutorial, then I see no point in spinning from multiple threads. Though, I am sure there is an application. I am not able to grasp the importance of it (especially MultiThreadedSpinner and AsyncSpinner) without applications and examples.

(Ques.3) Please give examples and suggest applications where I might use a multithreaded node and in-turn wait for callbacks (spin) from each separate thread.

If any of the questions seems trivial, please bear with me and explain.

Originally posted by McMurdo on ROS Answers with karma: 1247 on 2014-01-10

Post score: 6


1 Answer 1


Rosanswers logo

I think it's safe to say that, in general, you'd not use fork/exec within a ROS node. roslaunch serves that purpose for most cases.

You cited actionlib for your threading example. Yes, spinOnce is a proper (and non-buggy) way of handling callbacks. In this context, realize that ROS provides three types of inter-node interaction:

  • publish/subscribe is non-blocking and stateless (see '*Note' below)
  • service calls are blocking and stateful
  • actionlib calls are non-blocking and stateful

One uses an actionlib client when other 'work' needs to be done while the action is executing; that is, one thread will perform that 'work' while another keeps track of the action's progress. ROS's spin is a terminal call (i.e., non-returning until the node shuts down), with the effect that all message processing must be handled within the callbacks (and processing will only be done in the callbacks). Clearly that's inadequate for the other 'work'.

As an example, let's take a GUI for...oh, anything long-running, say navigation or object recognition. The 'work' that needs to be done is keeping the user interface responsive -- blocking the UI thread is a non-starter. For navigation, you likely want to update some representation of the current state with the actionlib feedback as it's received while the user interacts with other parts of the UI. For object recognition, it's likely not the feedback that's important, but rather the final results -- while the scene is being analyzed, the user (or the system internally) can 'work on' other things.

Some previously asked/answered spinOnce questions that you may want to look at:

*Note: in fact, it's exactly spinOnce that allows pub/sub to be non-blocking, as spin is terminal, and thus effectively blocks.

Originally posted by kramer with karma: 1470 on 2014-07-17

This answer was ACCEPTED on the original site

Post score: 7

Original comments

Comment by McMurdo on 2014-07-18:
I fully understand your answer. However, my question was not, "why would there be spinning in a multi-threaded program?" My question was, "why would there be multiple spins in a multi-threaded program, when there can be one thread that is perpetually spinning and the others waiting for a trigger?"

Comment by kramer on 2014-07-19:
Ah, OK. A single spinOnce will process all queued messages, but does so sequentially. Multiple and multi-threaded spinOnce calls provide concurrent message processing. That is, a long-running callback from a single spinOnce will hold up subsequent messages. More next comment...

Comment by kramer on 2014-07-19:
If callbacks are all very fast -- say, just data copying, with another thread actually processing -- you may never see any need for multiple spinOnce calls. In fact, that's what I've done for a large Qt project: a single spinOnce thread, quick callbacks, and additional threads for other processing.

Comment by McMurdo on 2014-07-19:
Great. If you have time, please also explain about callbacks and spining in nodelets. Perhaps there is already a question about that? And also what happens when we declare a NodeHandle and associate a queue to it in a Nodelet. I can make a new question if needed. Thanks

Comment by kramer on 2014-07-19:
You'd be better off searching for prior questions and/or opening another question, just to keep separate topics separate. (Besides, my nodelet experience is minimal.)


Your Answer

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