异步并发
import ray
import time
@ray.remote(max_concurrency=1)
class timeSleep():
def __init__(self, id):
self.id = id
def sleep(self, t):
for i in range(t):
time.sleep(1)
print("id:", self.id)
return t
if __name__ == '__main__':
ts_list = [timeSleep.remote(i) for i in range(3)]
trainers = {}
for i, runner in enumerate(ts_list):
trainers[runner.sleep.remote(i+5)] = runner
st = time.time()
for i in range(10000):
print("循环用时: ", time.time() - st)
st = time.time()
print("循环开始时间: ", st)
ready_runner_list, _ = ray.wait(list(trainers))
ready_id = ready_runner_list[0]
t = ray.get(ready_id)
runner = trainers.pop(ready_id)
for i in range(3):
time.sleep(1)
print("主程序")
trainers[runner.sleep.remote(t)] = runner ## 每次要重新调用一下actor的方法才行。同一个task id只能被执行一次。
st2 = time.time()
print("新的task id: ", runner.sleep.remote(t))
print("循环结束时间: ", st2)
- 以上代码可以异步并发,也就是说trainers里面的多个进程可以异步进行,且和主程序是并发的。也就是在一定情况下 主程序可以一直在执行。
- 这里要注意的是每次需要新建一个runner.sleep.remote(t),因为在ray里面一个task id只可以执行一次。所以当一个runner.sleep.remote(t)执行完以后,需要重新建一个。
比如:
一个task_ref 只会被执行一次
task_ref = ts_list[0].sleep.remote(3)
for i in range(10):
ray.get(task_ref)
下面这个就可以执行多次。可以看到每次的task个id都是不一样的。
for i in range(10):
task_ref = ts_list[0].sleep.remote(3)
print(task_ref)
ray.get(task_ref)
同一actor的并发情况
假设max_concurrency=1。
import ray
import time
import numpy as np
@ray.remote(max_concurrency=1)
class timeSleep():
def __init__(self):
self.i = 0
def sleep(self, t):
print("s1")
time.sleep(t)
# return t
def sleep2(self, t):
print("s2")
time.sleep(t)
if __name__ == '__main__':
ray.init()
assert ray.is_initialized()
ts = timeSleep.remote()
ray.get([ts.sleep.remote(10), ts.sleep2.remote(5)]) ## 一个actor 同一时刻只有一个方法在运行
- 上面这个case可以看到,即使是并发同一个actor里面的两个不同的方法,但是同一时刻也只会有一个task被执行。
- 同一方法肯定也是。