Python threading跟queue.Queue队列的实例

原因:你想定义跟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

你可能感兴趣的:(Python,Threading)