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

ROS中,ros::init()初始化的全局回调函数队列g_global_queue在spin()和spinOnce()中被检查并执行。回调函数通过subscribe和advertise添加到队列,如subcribe_options.h实现中。回调调用由spin()或spinOnce()内部的callOneCB(TLS*tls)单线程处理,spin阻塞等待,spinOnce仅执行一次。回调执行涉及线程锁和BOOST_SCOPE_EXIT机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

回调函数队列

首先, 通过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二者的区别就在于前者是阻塞等待, 而后者是只执行一次就结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值