title: Multithreading behaviour with ROS AsyncSpinner
body: <p>I am trying to understand how the AsyncSpinner from ROS really works because I may have something misunderstood. You can find a similar question <a href="https://answers.ros.org/question/228454/confusion-about-asyncspinner/" rel="noreferrer">here</a>.</p>
  
  <p>As seen <a href="https://answers.ros.org/question/53055/ros-callbacks-threads-and-spinning/" rel="noreferrer">here</a> its definition mentions:</p>
  
  <blockquote>
    <p><strong>Asynchronous spinner:</strong> spawns a couple of threads (configurable) that
    will execute callbacks in parallel while not blocking the thread that
    called it. The start/stop method allows to control when the callbacks
    start being processed and when it should stop.</p>
  </blockquote>
  
  <p>And in the official documentation <a href="http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning" rel="noreferrer">here</a> the AsyncSpinning is also remarked as a type of multi-threading Spinning.</p>
  
  <p>So, said that, I have a very simple example with a publisher and subscriber with an AsyncSpinner to test the multi-threading behavior. </p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include "ros/ros.h"
  #include "std_msgs/String.h"
  
  int main(int argc, char **argv)
  {
    ros::init(argc, argv, "publisher");
    ros::NodeHandle nh;
  
    ros::Publisher chatter_pub = nh.advertise&lt;std_msgs::String&gt;("chatter", 1000);
  
    ros::Rate loop_rate(10);
    while (ros::ok())
    {
      std_msgs::String msg;
      msg.data = "hello world";
  
      chatter_pub.publish(msg);
  
      ros::spinOnce();
  
      loop_rate.sleep();
    }
  
    return 0;
  }
  </code></pre>
  
  <p>And the subscriber where the spinner is defined and used:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include "ros/ros.h"
  #include "std_msgs/String.h"
  #include &lt;boost/thread.hpp&gt;
  
  int count = 0;
  
  void chatterCallback(const std_msgs::String::ConstPtr&amp; msg)
  {
    count++;
    ROS_INFO("Subscriber %i callback: I heard %s", count, msg-&gt;data.c_str());
    sleep(1);
  }
  
  int main(int argc, char **argv)
  {
    ros::init(argc, argv, "subscriber");
    ros::NodeHandle nh;
  
    ros::Subscriber sub = nh.subscribe("chatter", 1000, chatterCallback);
  
    ros::AsyncSpinner spinner(boost::thread::hardware_concurrency());
    ros::Rate r(10);
  
    spinner.start();
    ros::waitForShutdown();
  
    return 0;
  }
  </code></pre>
  
  <p>When I run both programs I get the following output:</p>
  
  <blockquote>
  <pre><code>[ INFO] [1517215527.481856914]: Subscriber 1 callback: I heard hello world
  [ INFO] [1517215528.482005146]: Subscriber 2 callback: I heard hello world
  [ INFO] [1517215529.482204798]: Subscriber 3 callback: I heard hello world
  </code></pre>
  </blockquote>
  
  <p>As you can see the callback runs every second and no other callbacks are being called in parallel. I know that the global callback queue is being fulfilled because if I stop the publisher, the subscriber will keep popping the accumulated messages from the queue.</p>
  
  <p>I know I should not block a callback but in the definition above is remarked that this will not stop the thread where it was called and I guess neither the others created by the spinner. Am I blocking the next callbacks just because I'm blocking the callback? Is there something I did misunderstood? I am bit confused and not able to demonstrate that the callbacks are running in parallel. Maybe you have another example?</p>