1. 程式人生 > >ros訂閱函式的多執行緒使用方法(C++: 外部變數控制跳出for迴圈)

ros訂閱函式的多執行緒使用方法(C++: 外部變數控制跳出for迴圈)

     

最初是想實現接收到某個some_topic然後解析內容,若是內容為指令action,action函式進入for迴圈,若是再接收到some_topic,裡面指令為stop則stop=true停止正在進行的action,跳出for迴圈(想用外部變數控制for迴圈的結束).

 類似:

 ros::NodeHandle n;
 ros::Subscriber sub = nh.subscribe(."some_topic",actionCallback..);
  .
  .
  .
 void actionCallback(..)
 {
    ROS_INFO("RECEVIED");
    if(command = "action")
     {
        action(3);
        ....
     }
    else if(command = "stop")
    {
     stop = true;
    }
 }
 
void action(int received)
  {
   for(int i=0; i<5;i++)
    {
      for(int j=0; j<4;j++)
     {
       std::cout<<received*i*j<<std::cout;
       ....

       if(stop)
       {
         
         break;//跳出第一層迴圈
       }
     }
      if(stop)
       {
         ROS_INFO("stop");
         break;//跳出第二層迴圈
       }
    ros::Duration(0.2).sleep();
   }
    stop = false; 
 }
然而不論stop為什麼變數,總會發現,進入for迴圈之後,若是迴圈沒有完成,即action沒有返回值.是不是接收下一個訊息的,從ROS_INFO的時間戳可以看出.

第二次列印的時間戳總是接著第一個時間戳,也就是說,若第一個訊息是action,第二個是stop,第三個是action,那麼第一action迴圈會完整執行一遍,第三個action的for迴圈一遍都不會執行.因此一個執行緒是完成不了stop想要的功能,因此想到一個方法,專門為stop開闢一個執行緒,用一個some_stop_topic,那麼就有兩個執行緒.

 

類似:
 ros::NodeHandle n;
 ros::Subscriber action_sub = n.subscribe(..."some_topic",actionCallback. ...);
 ros::Subscriber stop_action_sub = .subscribe(... "some_stop_topic",actionStopCallback....);
 ros::spin();
此時同樣進行測試,發現仍然沒有實現想要的功能,最後發現 ros::spin()還只是開闢了一個執行緒,我原本以為每一個callback均為一個執行緒,至今才恍然大悟.
參考文獻[1],發現此方法可以實線此功能:

 ros::NodeHandle n;
 ros::Subscriber action_sub = n.subscribe(..."some_topic",actionCallback. ...);
 ros::Subscriber stop_action_sub = .subscribe(... "some_stop_topic",actionStopCallback....);
 ros::MultiThreadedSpinner spinner(2); // Use 2 threads
 spinner.spin(); // spin() will not return until the node has been shutdown

用MultiThreadedSpinner說明此節點有兩個執行緒,也可用(boost::thread),最後堪堪實現了所需功能,但是由於for迴圈速度較快,而且沒有用lock,每次同樣時間傳送的stop,退出for迴圈的層次不一樣,因此還需好好思考.

 [1] http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning

 

若各位有好的方法解決我的問題,請不吝賜教.相互交流,非常感謝!

email: [email protected]