反模式:使用全局变量在任务和角色之间共享状态#
TLDR: 不要使用全局变量来与任务和角色共享状态。相反,将全局变量封装在一个角色中,并将角色句柄传递给其他任务和角色。
Ray 的驱动程序、任务和角色运行在不同的进程中,因此它们不共享相同的地址空间。这意味着如果你在一个进程中修改全局变量,这些更改不会反映在其他进程中。
解决方案是使用一个actor的实例变量来保存全局状态,并将actor句柄传递到需要修改或访问状态的地方。请注意,不支持使用类变量在同一类的实例之间管理状态。每个actor实例都在其自己的进程中实例化,因此每个actor都会有类变量的自己的副本。
代码示例#
反模式:
import ray
ray.init()
global_var = 3
@ray.remote
class Actor:
def f(self):
return global_var + 3
actor = Actor.remote()
global_var = 4
# This returns 6, not 7. It is because the value change of global_var
# inside a driver is not reflected to the actor
# because they are running in different processes.
assert ray.get(actor.f.remote()) == 6
更好的方法:
@ray.remote
class GlobalVarActor:
def __init__(self):
self.global_var = 3
def set_global_var(self, var):
self.global_var = var
def get_global_var(self):
return self.global_var
@ray.remote
class Actor:
def __init__(self, global_var_actor):
self.global_var_actor = global_var_actor
def f(self):
return ray.get(self.global_var_actor.get_global_var.remote()) + 3
global_var_actor = GlobalVarActor.remote()
actor = Actor.remote(global_var_actor)
ray.get(global_var_actor.set_global_var.remote(4))
# This returns 7 correctly.
assert ray.get(actor.f.remote()) == 7