multi-threaded spinner

Application Scenario

  • Suppose that we have two callbacks (talker1 and talker2) running at 1Hz in the same ros node. The talker2 callback can be blocked if the talker1 callback takes more than 1s. Because ros::spin() is single-threaded.

  • Note: this issue only happens with roscpp. The rospy spinner is already multi-threaded, so you won’t be able to reproduce this issue if you translate the cpp subscriber node to Python.

Solution One: MultiThreadedSpinner

  • Blocking method. Simply just increase the number of threads to process callback queues.

ros::MultiThreadedSpinner spinner(4); // Use 4 threads; or 0 to use all threads
spinner.spin(); // spin() will not return until the node has been shutdown

Solution Two: AsyncSpinner

  • Non-blocking method. Try to get each callback a thread if available.

int main(int argc, char **argv) {
    ros::init(argc, argv, "talker_subscribers");
    ros::NodeHandle nh;
    ros::AsyncSpinner spinner(0); // 0 means max number of threads available
    spinner.start();  // start the AsyncSpinner asynchronously (non-blocking)
    ros::Subscriber counter1_sub = nh.subscribe("talker1", 10, callbackTalker1);
    ros::Subscriber counter2_sub = nh.subscribe("talker2", 10, callbackTalker2);
    ros::waitForShutdown(); // block the program; wait for the node to be killed
    // alternatively, you may have an infinite loop here to process some data
}

References: http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning; https://roboticsbackend.com/ros-asyncspinner-example; https://levelup.gitconnected.com/ros-spinning-threading-queuing-aac9c0a793f

Last updated