首先要了解的一點是,任何一個釋出和訂閱,都會有其對應的釋出緩存區和訂閱緩存區,正如advertise和subscribe函數中都有緩存數量的參數。當有釋出者釋出消息後,會存放在釋出緩存區,如果該topic有訂閱者,則從釋出緩存區讀取到訂閱緩存區,等待被使用。
spin()和spinOnce()的目的都是将消息從訂閱緩存區拿到回調函數中去,那麼這兩者有什麼差別呢?
spinOnce()
當程式運作到spinOnce()時,程式到相應的topic訂閱緩存區檢視是否存在消息,如果有消息,則将消息傳入回調函數執行回調函數;如果沒有消息則繼續向後執行。spinOnce()并不是等待到一個消息才向後執行,而是檢視有沒有消息!
spin()
當程式運作到spin()時,程式同樣去相應的topic訂閱緩存區檢視是否有消息,如果有消息,則将消息傳入回調函數;如果沒有消息則重複上述過程。是以spin()可以當作是對spinOnce()的循環,即:
while(1)
{
ros::spinOnce();
}
顯然,spin()後面的代碼将不會再被執行,表現出來的功能就是持續等待消息。
總結
剛接觸ros時,以為消息機制會類似于android的監聽機制,即開啟監聽後就啟動了監聽線程在背景不斷等待消息,有消息後馬上就可以傳入回調函數開始執行。而實際實驗後發現隻有運作到spin()及spinOnce()時才會去檢視消息。