Rosanswers logo

Hi, my node as a class which calls a service. During that service call it needs to get notified by a topic. The callback is set up respectively. The problem is that during the service call no messages are received. I suspect that the node is blocked by the service call and cannot handle any callback calls. They just pop up after the service call has terminated.

Below is a similar example of that node.

class MyClass {
       my_srv.call(request);  // blocking here!
       // do something <-- is never called during service request
int main.. {
  ros::ServiceClient my_srv = n.serviceClient<..>("..");
  MyClass my_class(my_srv);
  n.subscribe(my_topic, 100, &MyClass::callback, &my_class);

When trying to put the service call in another boost thread compilation leads to the error (see below)

 my_srv.call(request);  // blocking here!

Changed to:

 boost::thread myThread = boost::thread(boost::bind(&ros::ServiceClient::call, &my_srv, request));


 »bind(<unresolved overloaded function type>, ros::ServiceClient*, request&)«

Any hints? Thanks

Originally posted by Sebastian Rockel on ROS Answers with karma: 23 on 2015-01-09

Post score: 0


1 Answer 1


Rosanswers logo

Hi Sebastian,

a couple of points:

  • Service calls are blocking. This is a deliberate design decision. IMO, services should in general only be used for things which return quickly. If you want to query a long-running service asynchronously, that's a sign that that service should better be implemented as an actionlib action. (... assuming you control the implementation of the service, that is.)
  • Your topic callbacks aren't triggered because they only are triggered when your node enters ros::spin() or ros::spinOnce(). In roscpp, there are threads which handle topics asynchronously, but they only fill the subscriber queues. When you call ros::spin(), your thread goes through the messages in the subscriber queues one by one and calls the corresponding callbacks. This means that if you're only using ros::spin(), your code won't be multi-threaded.
  • A good solution for your problem could be the ros::AsyncSpinner class. It starts a user-defined number of threads which all call ros::spin(), so you don't have to call it yourself any more. The drawback (as with any multi-threaded solution) is of course that now you need to make sure that all resources are properly locked to prevent data races.

Hope this helps!

Originally posted by Martin Günther with karma: 11816 on 2015-01-09

This answer was ACCEPTED on the original site

Post score: 3

Original comments

Comment by Sebastian Rockel on 2015-01-09:
Hi Martin, Thanks!

  • I understand the second point and regarding the first point I completely agree. Unfortunately it's not my package and it was designed by uos like this on purpose;-)

  • ros::AsyncSpinner looks interesting. I'll have a look if I can solve the problem pragmatically with it.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.