我的问题是,如果我重新分配列表中的一个项目,使其在并行过程中发生重新分配,那么在并行过程结束后,该变化会恢复到其原始状态。
在下面的例子中--为了便于理解而大大简化--我有一个函数将列表元素NoZeros[0]改为 "chicken",第二个函数将NoZeros[1]改为 "sandwich"。我甚至在第二个函数中加入了 "全局",只是为了证明这不是一个局部与全局的问题--它看起来像一个问题,但它确实不是。当你运行程序时,打印命令会告诉你,列表元素确实发生了变化。问题是在这些过程之后调用NoZeros时,NoZeros还是原来的样子,而不是"["鸡肉","三明治"]。
我知道python的多进程包也有一模一样的问题,但解决的方法是把你想不还原的东西 "一步到位",然后在它之前的地方贴上 "manager.list()"。我的问题是,我一辈子都搞不清楚雷的等价物是什么。例如,在Python的多处理库中,你只需要在NoZeros被改变之前的某个地方写NoZeros=manager.list(NoZeros),这就结束了,但我找不到Ray的等价物,或者是否有等价物。
如何使用RAY在parallel中改变列表?非常感谢。
另外:请注意这个脚本可能会让你陷入一个循环,因为你可能会在并行进程完成之前打印NoZeros。这是我遇到的另一个bug,希望得到关注,但这不是优先级。我想说的是,你可能想在下一个单元格中运行print(NoZeros)(至少Jupyter有这个功能)。在 python 的多处理库中,我们只需执行 "process.join()",就能解决结束相关进程的问题,所以这让我想到了额外的问题。
额外的问题: 如何让ray.wait()工作;如何告诉我的代码只有在前面的命令--即使是并行命令--完成后,才会进入下一个命令?
'''
import ray
ray.shutdown()
ray.init()
NoZeros=[0,0]
@ray.remote
def Chicken():
print("NoZeros[0] is",NoZeros[0],"but will change to chicken")
NoZeros[0]="chicken"
print("Now, NoZeros[0] is",NoZeros[0])
@ray.remote
def GlobalSandwich():
global NoZeros #This is just to show that "global" doesn't solve anything
print("NoZeros[1] is",NoZeros[1],"but will change to sandwich")
NoZeros[1]="sandwich"
print("Now, NoZeros[1] is",NoZeros[1])
Chicken.remote()
GlobalSandwich.remote()
#Unhash these 3 lines of code if youd like to try tackling another question: why does ray.wait() not work?
#How do i wait until parallel processes end, so i can continue my code?
#WaitList=[Chicken.remote(),GlobalSandwich.remote()]
#ray.wait(WaitList)
#print("If you see this first, ray.wait() isnt working")
#This line of code right here was executed in the next command line (Jupyter); this print command happens when the other processes are finished
print(NoZeros)
'''
在Ray中,可变的全局状态应该存在于 演员. 例如,你可以做这样的事情。
@ray.remote
class ListActor:
def __init__(self, l):
self._list = l
def get(self, i):
return self._list[i]
def set(self, i, val):
self._list[i] = val
def to_list(self):
return self._list
然后为了使用它,你可以把它作为一个参数传递进去(同样,你不应该依赖全局变量)。
NoZeros = ListActor.remote([0,0])
@ray.remote
def Chicken(NoZeros):
print("NoZeros[0] is",ray.get(NoZeros.get.remote(0)),"but will change to chicken")
NoZeros.set(0, "chicken")
print("Now, NoZeros[0] is",ray.get(NoZeros.get(0)))
# We need to make sure this function finishes executing before we print.
ray.get(Chicken.remote(NoZeros))
print(ray.get(NoZeros.to_list.remote()))