ROS的单线程Spinning和多线程Spinning
单线程Spinning
ros::spin()是最简单的单线程自旋, 它会一直调用直到结束
用法: ros::spin();
另一个单线程spinning是ros::spinOnce(),它定期调用等待在那个点上的所有回调
用法: ros::spinOnce();
简单的我们自己实现一个用法相同的ros::spin()
这样: ros::getGlobalCallbackQueue()->callAvailable(ros::WallDuration(0.1));
ros::spinonce
这样: ros::getGlobalCallbackQueue()->callAvailable(ros::WallDuration(0));
以上,是它的基础用法,那么spin到底做了什么呢?
首先, 当我们调用ros::spin时, 会有一个互斥锁, 把你的回调队列加锁, 防止执行混乱.
然后, 检测如果回调队列不为空, 则读取回调队列
最后,当while(nh.ok())为true时, 调用当前队列中的所有函数,如果有不满足的, 会重新放回队列中
所以listener中, 就一直执行这ros::spin来监听话题了.从这样看来,spin和spinOnce的区别之一,就是while(nh::ok())执行块的大小了. 另一个是等待时间, spin在执行时, 会指定一个返回前可以等待调用的时间. spin会等待0.1s而spinonce不会
spinOnce使得pub/sub为非阻塞锁 spin是客户端的, 因此是阻塞的.
这样就很好理解talker要用SpinOnce,有需要talk的时候发出,没有的时候不发送.而listener一直在阻塞着听
这样,再来说之前很流传的一句关于解释spin的话, "所有的回调函数都是spin调用的". 这是一句形象而不准确的话. 回调函数一直等待在回调队列中, 只要条件一满足就会发生回调, 而spin的作用, 只是创建了线程给这个回调函数去执行它, 这样多线程就不会影响其他的作业.
之所以用spin, 是因为rospy不愿指定线程模型, 在程序中将线程暴露出来, 而用spin来把它封装起来. 但你可以用多线程调用任意数量的回调函数.
没有用户订阅, 服务和回调是不会被调用的.
多线程Spinning
多线程Spinning
roscpp内部支持调用多线程, 有两个:
ros::MultiThreadedSpinner
ros::MultiThreadedSpinner是阻塞微调, 类似于ros::spin(), 你可以在它的构造函数中指定线程数量, 但如果不指定或者设为0, 它会根据你的CPU内核数创建线程.
ros::MultiThreadedSpinner spinner(); // Use 4 threads
spinner.spin(); // spin() will not return until the node has been shutdown
ros::AsyncSpinner (since 0.10)
一个更有用的线程spinner是AsyncSpinner. 与阻塞的spin()不同, 它有start()和stop()调用, 并且在销毁时自动停止
ros::AsyncSpinner spinner(); // Use 4 threads
spinner.start();
ros::waitForShutdown();
ROSCPP的哲学是"工具, 而非框架"
另外: 不知道大家会把spin spinner spinning怎么译呢, 自旋?微调还是什么(蜘蛛么...反正肯定不会是棒槌`_`)
ROS的单线程Spinning和多线程Spinning的更多相关文章
- GDB:从单线程调试到多线程调试(MFiX单步调试)
GDB:从单线程调试到多线程调试 1. 裸跑GDB 1.1 安装GDB sudo apt-get install gdb 1.2 编译程序 由于需要调试,因此编译的时候需要添加-g编译参数: 1.3 ...
- JAVA单线程以及java多线程的实现方式
1.java单线程的实现 public class SingletonThread { @SuppressWarnings("static-access") public stat ...
- C#winform单线程事例与多线程事例
通过例子编写,用winform编写的,讲解单线程与多线程使用,用于异步加载数据,界面不会卡死,数据在后台默认加载,给用户更好的体验.稍后会附加完整代码. 1.先不用线程,显示一个求和,计算过程中要停留 ...
- 在单进程单线程或单进程多线程下实现log4cplus写日志并按大小切割
基于脚本配置来过滤log信息 除了通过程序实现对log环境的配置之外.log4cplus通过PropertyConfigurator类实现了基于脚本配置的功能.通过 脚本能够完毕对logger.app ...
- 单线程爬虫VS多线程爬虫的效率对比
单线程爬虫: import re import requests import time url_EB = 'http://www.amazon.com/gp/search/other/ref=sr_ ...
- GUI为什么不设计为多线程(用户事件和底层事件的流程是相反的,每层都加锁效率太低,共用一把锁那就是单线程)
在我们这批新人转正评审的时候,我师父问了我的小伙伴一个问题:为什么一些更新界面的方法只能在主线程中调用?师父没有问我这个问题,让知其然但不知其所以然的我有种侥幸逃过一难的心情.我想如果回答那是因为An ...
- 在 Windows 10 中使用 OpenAI Spinning Up
前段时间,openAI 发布了 Spinning Up ,本篇博客将介绍如何在 Windows 系统中使用 Spinning Up. 什么是 Spinning Up 先来说说 Spinning Up, ...
- JS异步解决方案之概念理解-----------阻塞和非阻塞,同步和异步,并发和并行,单线程和多线程
首先记住一句话,JS是单线程的. 单线程意味着什么?单线程意味着 它不能依靠自己实现异步. JS实现的异步,往往都是靠 浏览器.Node 的机制(事件驱动.回调)实现的. 下面让我这个单身狗 以谈恋爱 ...
- PHP是单线程还是多线程?
PHP 从设计之初到流行起来都没有出现明显需要用多线程才能解决的需求.某些需要用到多线程的地方也有相应的解决方案和替代方案.多线程并不总是比单线程优,多线程可能会引入其他问题(例如:两个线程同时调用一 ...
随机推荐
- LINUX的磁盘管理du命令详解
LINUX的磁盘管理du命令详解 du(disk usage)命令可以计算文件或目录所占的磁盘空间.没有指定任何选项时, 它会测量当前工作目录与其所有子目录,分别显示各个目录所占的快数,最后才显示工作 ...
- js兼容性问题总结
JS中出现的兼容性问题的总结1.关于获取行外样式 currentStyle 和 getComputedStyle 出现的兼容性问题 我们都知道js通过style不可以获取行外样式,当我们需要获取行外 ...
- [课程设计]Scrum 3.2 多鱼点餐系统开发进度(页面优化&下单详细信息页面)
Scrum 3.2 多鱼点餐系统开发进度(页面优化&下单详细信息页面) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选 ...
- 深入分析ClassLoader
首先介绍下ClassLoader: ClassLoader顾名思义就是类加载器,负责将Class加载到JVM中,事实上ClassLoader除了能将Class加载到JVM中之外,还有一个重要的作用就是 ...
- c++打开浏览器
调用外部命令 如果用默认浏览器,就调用ShellExecute(NULL, _T("open"), _T("explorer.exe"), _T("h ...
- Python mysql sqlite 数据没有更新
原因 MySQL事务隔离级别 解决方案 conn.commit() conn.close()
- Win8下Visual Studio编译报“无法注册程序集***dll- 拒绝访问。请确保您正在以管理员身份运行应用程序。对注册表项”***“的访问被拒绝。”问题修正(转)
原来在Win7下Visual Studio跑的好好的程序,现在在Win8下编译报“无法注册程序集***dll- 拒绝访问.请确保您正在以管理员身份运行应用程序.对注册表项”***“的访问被拒绝.”的错 ...
- web前端之HTML的前世今生
一个尖括号 < 一个尖括号能干什么 < ? 你可以编出一顶帽子 <(:-p 或一张笑脸 :-> 或诉说一份爱 <3 或者更直接一些 <!DOC ...
- 关于引用JS和CSS刷新浏览器缓存问题
有时候我们会碰到上线的新版本都要刷新一次缓存的问题.那是因为改了JS的内容,但是JSP引用的地方后面的字符串未发生改变导致浏览器读取浏览器缓存而不会重新加载新的JS内容,以下提供两种解决方式: 1.每 ...
- dm9000网口收发控制以及mac地址过滤设置
目的 :完成网口收发调试 过程 : 1.网口初始化,根据芯片数据手册配置 2.网口发数,先向DM9000中的TX FIFO存入数据,然后出发发送寄存器完成发送: 3.网口接收 . ...