Multithreading behaviour with ROS AsyncSpinner Multithreading behaviour with ROS AsyncSpinner multithreading multithreading

Multithreading behaviour with ROS AsyncSpinner


Short answer:

ROS callbacks are threadsafe by default. This means a registered callback can only be processed by one thread and concurrent calls are disabled. A second thread is not able to access the same callback at the same time.

If you register a second callback, you will see the spinner working like expected and multiple threads are calling your callbacks at the same time.

ros::Subscriber sub1 = nh.subscribe("chatter", 1000, chatterCallback);ros::Subscriber sub2 = nh.subscribe("chatter", 1000, chatterCallback);

Extended answer:

An async spinner tries to call available callbacks in the callback queue as fast as the rate allows. If the callback is already in process (by an other thread) the CallResult is TryAgain. This means a new attempt will be started later on.

The implementation of this lock uses the variable allow_concurrent_callbacks_ which means this behaviour is optional.

Solution:

It is possible to allow concurrent calls by setting the correct SubscribeOptions.allow_concurrent_callbacks which is false by default. Therefore you need to define your own SubscribeOptions. Here is the code you need to subscribe and allow concurrent callback calls:

ros::SubscribeOptions ops;ops.template init<std_msgs::String>("chatter", 1000, chatterCallback);ops.transport_hints = ros::TransportHints();ops.allow_concurrent_callbacks = true;ros::Subscriber sub = nh.subscribe(ops);