Husky提供了broadcast/get_response APIs,用于广播变量给集群中所有的worker。在某些情况下,广播变量比使用send_message更加高效。Husky 还提供了request/list_reply/get_response APIs来向特定的对象发送获取某些变量值的请求。
以下例子使用broadcast APIs来计算任意两个点之间的距离。假设全部点的数目为num_pts
,这些点存在pt_list
上,和调用get_coordinates()
方法将返回一个点的坐标值,表示为std::vector<double>
的容器。
worker.list_execute(pt_list, [&](Point & pt) { worker.broadcast(pt, pt.get_coordinates()); }); worker.list_execute(pt_list, [&](Point & pt) { for (int i = 0; i < num_pts; i++) { auto other_pt = pt.get_response<std::vector<double>>(i); calc_distance(t, other_pt); } });
在第一个list_execute
中,我们广播每一个点(及其包含的所有的内容)到每一台机器上面。广播的内容必须在每一台机上面被检索到。Husky用key来区分并检索不同的广播内容。也就是,broadcast
中的第二个参数就是我们想要广播的内容,第一个参数将作为该key,为get_response
使用来获取该内容。
因此,在第二个list_execute
中,利用key,我们使用get_response
来获取获取所需的广播内容。
如下是broadcast 和 get_response的函数声明:
template<typename ObjT, typename MsgT> void broadcast(const ObjT& obj, const MsgT& msg); template<typename MsgT, typename KeyT> MsgT& get_response(KeyT const& key);
下面的例子展示了如何使用request/list_reply/get_response
API。实现的功能是,puller_list
中的每个点,向pullee_list发出request请求。
pullee_list`中的点收到请求后,会把他id发送回去。
worker.list_execute(puller_list, [&](Puller& puller) { worker.request(puller.id(), pullee_list); }); worker.list_reply(pullee_list, [](Pullee& pullee) { return pullee.id(); }); worker.list_execute(puller_list, [&](Puller& puller) { auto pullee_id = puller.get_response<int>(puller.id()))); });
在第一个list_execute
中, 每一个worker对puller_id
所索引的pullee_list
中的对象发出请求. 接着,我们使用list_reply
函数来表明在pullee_list
中被请求的对象该如何做出反应。在这里,我们仅仅简单的让它返回了自己的id。在最后的list_execute
中, puller就可以收到回应。
函数request, list_reply and get_response的声明如下:
template<typename TargetObjT> void request(typename TargetObjT::KeyT const& key, ObjList<TargetObjT>& obj_list); template<typename ObjT, typename ReplyT> void list_reply(ObjList<ObjT>& obj_list, ReplyT reply); template<typename MsgT, typename KeyT> MsgT& get_response(KeyT const& key);