参与者模式:【摘自维基百科】
参与者模型推崇的哲学是“一切皆是参与者”,这与面向对象编程的“一切皆是对象”类似,但是面向对象编程通常是顺序执行的,而参与者模型是并行执行的。
参与者是一个运算实体,回应接受到的消息,同时并行的:
- 发送有限数量的消息给其他参与者;
- 创建有限数量的新参与者;
- 指定接受到下一个消息时的行为。
- 以上操作不含有顺序执行的假设,因此可以并行进行。
发送者与已经发送的消息解耦,是参与者模型的根本优势。这允许进行异步通信,同时满足消息传递的控制结构。
消息接收者是通过地址区分的,有时也被称作“邮件地址”。因此参与者只能和它拥有地址的参与者通信。它可以通过接受到的信息获取地址,或者获取它创建的参与者的地址。
参与者模型的特征是,参与者内部或之间进行并行计算,参与者可以动态创建,参与者地址包含在消息中,交互只有通过直接的异步消息通信,不限制消息到达的顺序。
python yield 实现的参与者模式:【摘自python3-cookbook】
from collections import deque
class ActorScheduler:
def __init__(self):
self._actors = { } # Mapping of names to actors
self._msg_queue = deque() # Message queue
def new_actor(self, name, actor):
'''
Admit a newly started actor to the scheduler and give it a name
'''
self._msg_queue.append((actor,None))
self._actors[name] = actor
def send(self, name, msg):
'''
Send a message to a named actor
'''
actor = self._actors.get(name)
if actor:
self._msg_queue.append((actor,msg))
def run(self):
'''
Run as long as there are pending messages.
'''
while self._msg_queue:
actor, msg = self._msg_queue.popleft()
try:
actor.send(msg)
except StopIteration:
pass
# Example use
if __name__ == '__main__':
def printer():
while True:
msg = yield
print('Got:', msg)
def counter(sched):
while True:
# Receive the current count
n = yield
if n == 0:
break
# Send to the printer task
sched.send('printer', n)
# Send the next count to the counter task (recursive)
sched.send('counter', n-1)
sched = ActorScheduler()
# Create the initial actors
sched.new_actor('printer', printer())
sched.new_actor('counter', counter(sched))
# Send an initial message to the counter to initiate
sched.send('counter', 10000)
sched.run()