原因:你想定义跟actor模式中类似“actors”角色的任务
from queue import Queue
from threading import Thread, Event
# Sentinel used for shutdown
class ActorExit(Exception):
pass
class Actor:
def __init__(self):
self._mailbox = Queue()
def send(self, msg):
'''
Send a message to the actor
'''
self._mailbox.put(msg)
def recv(self):
'''
Receive an incoming message
'''
msg = self._mailbox.get()
if msg is ActorExit:
raise ActorExit()
return msg
def close(self):
'''
Close the actor, thus shutting it down
'''
self.send(ActorExit)
def start(self):
'''
Start concurrent execution
'''
self._terminated = Event()
t = Thread(target=self._bootstrap)
t.daemon = True
t.start()
def _bootstrap(self):
try:
self.run()
except ActorExit:
pass
finally:
self._terminated.set()
def join(self):
self._terminated.wait()
def run (self):
pass
'''
由用户实现的运行方法
'''
# while True:
# msg = self.recv()
1.简单实例
class PrintActor(Actor):
# 重写函数
def run (self):
while True:
msg = self.recv()
print('Got:', msg)
# Sample use
p = PrintActor()
p.start()
p.send('Hello')
p.send('World')
p.close()
p.join()
输出:
Got: Hello
Got: World
2.以元组形式传递标签消息,让actor执行不同的操作
class TaggedActor(Actor):
def run (self):
while True:
tag, *payload = self.recv()
getattr(self, 'do_' + tag)(*payload)
# Methods correponding to different message tags
def do_A (self, x):
print('Running A', x)
def do_B (self, x, y):
print('Running B', x, y)
# Example
a = TaggedActor()
a.start()
a.send(('A', 1)) # Invokes do_A(1)
a.send(('B', 2, 3)) # Invokes do_B(2,3)
a.close()
a.join()
输出:
Running A 1
Running B 2 3
3. 一个类actor对象的 send() 方法可以被编程让它能在一个套接字连接上传输数据 或通过某些消息中间件(比如AMQP、ZMQ等)来发送。
class Result:
def __init__ (self):
self._evt = Event()
self._result = None
def set_result (self, value):
self._result = value
self._evt.set()
def result (self):
self._evt.wait()
return self._result
class Worker(Actor):
def submit (self, func, *args, **kwargs):
r = Result()
self.send((func, args, kwargs, r))
return r
def run (self):
while True:
func, args, kwargs, r = self.recv()
r.set_result(func(*args, **kwargs))
# Example use
worker = Worker()
worker.start()
r = worker.submit(pow, 2, 3)
print(r.result())
输出:
8