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內核數創建線程.

1 ros::MultiThreadedSpinner spinner(4); // Use 4 threads
2 spinner.spin(); // spin() will not return until the node has been shutdown

ros::AsyncSpinner (since 0.10)

一個更有用的線程spinner是AsyncSpinner. 與阻塞的spin()不同, 它有start()和stop()調用, 並且在銷毀時自動停止

1 ros::AsyncSpinner spinner(4); // Use 4 threads
2 spinner.start();
3 ros::waitForShutdown();

 

 

ROSCPP的哲學是"工具, 而非框架"

另外: 不知道大家會把spin spinner spinning怎么譯呢, 自旋?微調還是什么(蜘蛛么...反正肯定不會是棒槌`_`)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM