ros2 python call_async(异步回调)方法求助
-
ros2 不建议使用同步请求,但是在实际的场景中,同步请求没办法避免,所以为了实现同步效果,我在异步请求的回调函数中修改成员变量的值,当值改变时确定回复已收到,代码为:
client.call_async(request).add_done_callback(self.callback) time.sleep(0.004) if(self.is_ok): print('ok')
在
callback(self)
函数中会修改self.is_ok为True。
在实际测试中,使用这种策略可以在我笔记本电脑中正常输出ok,但是换一台台式电脑,异步的回调函数一直等到当前函数执行完成后才会执行,台式电脑中,异步回调函数的线程id和主函数相同,好像异步回调一直被主线程卡住。
有大佬了解异步回调的机制,或者有什么比较好使的方法能够完成同步请求吗?(python和c++都能聊聊) -
@Lorry 可以给服务的客户端一个单独的回调组,相当于有数据来了到另外一个回调组进行处理,这样就不会卡主线程,等另外一个回调组处理完,你的is_ok设成true,这样就可以在主线程进行检测
-
@Lorry 也可以这样,你单独开回调组给客户端的回调函数,然后你的后续逻辑直接在回调函数调用,也可以保证时序
-
@小鱼 程序中我确实也给client单独指定了回调组,类型是ReentrantCallbackGroup,笔记本电脑中确实是回调和主线程不卡,但是在台式机中,回调一定要等到主线程执行完才会执行
-
@小鱼 在 ros2 python call_async(异步回调)方法求助 中说:
@Lorry 可以给服务的客户端一个单独的回调组,相当于有数据来了到另外一个回调组进行处理,这样就不会卡主线程,等另外一个回调组处理完,你的is_ok设成true,这样就可以在主线程进行检测
回调组如果指定类型为ReentrantCallbackGroup,即便多个订阅或者client都使用同一个回调组, 应该不会相互阻塞吧?
-
@Lorry 虽然回调组在单独的县城了,但启动回调的线程还是主线程,所以主线程不要阻塞,要做阻塞的事情单独开线程做。
-
ros2同步调用其实是好用的,虽然文档里写的不建议用。
其次可以试试将异步调用封装成同步的future = call_async(request) while True: if future.done(): break
-
@1522346936 我之前也是这样使用,但是经常出问题,会出现死循环。还是需要把异步调用封装成同步才行