python协程引擎最小实现代码分析(136行,绝对教学经典!)

一、协程引擎代码(asyncio_slow.py)

import time
import logging

log = logging.getLogger("asyncio")

# Workaround for not being able to subclass builtin types
class LoopStop(Exception):
    pass

class InvalidStateError(Exception):
    pass

# Object not matching any other object
_sentinel = []

class EventLoop:
    def __init__(self):
        self.q = []
        
    def call_soon(self, c, *args):
        self.q.append((c, args))

    def call_later(self, delay, c, *args):
        def _delayed(c, args, delay):
            yield from sleep(delay)
            self.call_soon(c, *args)
        Task(_delayed(c, args, delay))
	
	#事件主循环,执行协程队列中待处理协程
    def run_forever(self):
        while self.q:
            c = self.q.pop(0)
            try:
                c[0](*c[1])   #调用真正需要执行的协程函数代码
            except LoopStop:
                return
        # I mean, forever
        while True:
            time.sleep(1)

    def stop(self):
        def _cb():
            raise LoopStop
        self.call_soon(_cb)

    def run_until_complete(self, coro):
        t = ensure_future(coro)
        t.add_done_callback(lambda a: self.stop())
        self.run_forever()

    def close(self):
        pass

_def_event_loop = EventLoop()

class Future:
    def __init__(self, loop=_def_event_loop):
        self.loop = loop
        self.res = _sentinel
        self.cbs = []

    def result(self):
        if self.res is _sentinel:
            raise InvalidStateError
        return self.res

    def add_done_callback(self, fn):
        if self.res is _sentinel:
            self.cbs.append(fn)
        else:
            self.loop.call_soon(fn, self)

    def set_result(self, val):
        self.res = val
        for f in self.cbs:
            f(self)

class Task(Future):
    def __init__(self, coro, loop=_def_event_loop):
        super().__init__()
        self.loop = loop
        self.c = coro
        # upstream asyncio forces task to be scheduled on instantiation
        #将任务加入协程事件循环中
        self.loop.call_soon(self)
	
	#执行下一个协程
    def __call__(self):
        try:
            next(self.c)
            self.loop.call_soon(self)
        except StopIteration as e:
            log.debug("Coro finished: %s", self.c)
            self.set_result(None)

def get_event_loop():
    return _def_event_loop

# Decorator
def coroutine(f):
    return f

def ensure_future(coro):
    if isinstance(coro, Future):
        return coro
    return Task(coro)

class _Wait(Future):
    def __init__(self, n):
        Future.__init__(self)
        self.n = n

    def _done(self):
        self.n -= 1
        log.debug("Wait: remaining tasks: %d", self.n)
        if not self.n:
            self.set_result(None)

    def __call__(self):
        pass

def wait(coro_list, loop=_def_event_loop):
    w = _Wait(len(coro_list))

    for c in coro_list:
        t = ensure_future(c)
        t.add_done_callback(lambda val: w._done())

    return w

def sleep(secs):
    t = time.time()
    log.debug("Started sleep at: %s, targetting: %s", t, t + secs)
    while time.time() < t + secs:
        time.sleep(0.01)
        yield    #	#让出执行权
    log.debug("Finished sleeping %ss", secs)

二、使用引擎例子

import asyncio_slow as asyncio

@asyncio.coroutine
def greet_every_two_seconds():
    while True:
        print('Hello World')
        yield from asyncio.sleep(2)

if __name__ == '__main__':
	loop = asyncio.get_event_loop()
	loop.run_until_complete(greet_every_two_seconds())
import asyncio_slow as asyncio

@asyncio.coroutine
def factorial(name, number):
    f = 1
    for i in range(2, number+1):
        print("Task %s: Compute factorial(%s)..." % (name, i))
        yield from asyncio.sleep(1)
        f *= i
    print("Task %s: factorial(%s) = %s" % (name, number, f))

if __name__ == '__main__':
	tasks = [
    	asyncio.Task(factorial("A", 2)),
    	asyncio.Task(factorial("B", 3)),
    	asyncio.Task(factorial("C", 4))]

	loop = asyncio.get_event_loop()
	loop.run_until_complete(asyncio.wait(tasks))
	loop.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值