关于ROS中的spin和spinOnce的理解、

回调函数队列

首先, 通过ros::init()函数会创建一个回调函数队列, 即g_global_queue, 而该队列会在spin函数和spinOnce函数中被轮询检测是否需要有消息到达, 有回调函数需要执行, 回调函数的定义的数据类型为 struct CallbackInfo

Subcribe函数和Advitise函数会将回调添加到队列中

该队列会将nodeHandle下的回调函数, 以及NodeHandle::subscribe()/NodeHandle::advertise()的回调函数添加到回调函数队列当中。
例如,在subcribe_options.h头文件的实现, 将helper函数添加到队列当中。

bool was_full = false;
info->subscription_queue_->push(info->helper_, des, info->has_tracked_object_, info->tracked_object_, true, latch_info.receipt_time, &was_full);
if (!was_full)
{
   info->callback_queue_->addCallback(info->subscription_queue_, (uint64_t)info.get());
} // info的数据类型为struct CallbackInfo

回调函数如何被调用

回调函数本质上,都在是spin()或者spinOnce()函数内通过函数callOneCB(TLS* tls) 来实现, 该函数是一种单线程的实现,内部添加了对应的线程锁, 然后通过BOOST_SCOPE_EXIT() BOOST_SCOPE_EXIT_END来实现函数的回调。spin和spinOnce二者的区别就在于前者是阻塞等待, 而后者是只执行一次就结束。

你可能感兴趣的:(ros,ros)