python loop call soon_python3-asyncio 学习笔记 1 -- call_soon

最近在学习python3 的 asyncio, 特将学习笔记记录于此.

先来个简单的例子:

import asyncio

def hello_world(loop):

print('Hello World')

loop.stop()

loop = asyncio.get_event_loop()

# Schedule a call to hello_world()

loop.call_soon(hello_world, loop)

# Blocking call interrupted by loop.stop()

loop.run_forever()

loop.close()

可以看到先是通过

asyncio.get_event_loop()

得到事件循环,而这是 selector_events.BaseSelectorEventLoop 、base_events.BaseEventLoop 的一个实例.。之后调用 call_soon以达到立即执行的目的,这个 call_soon来自base_events.BaseEventLoop ,实际的是抛给了 events.Handle,生成了一个 Handle的实例,实际执行是 Handle._run, 但是在实例 Handle后并没有立即调用_run,而是将生成的 Handle 实例添加到了 base_events.BaseEventLoop. _ready 中,直到调用

loop.run_forever()

才开始执行, 那么这个 loop.run_forever() 做了啥?

def run_forever(self):

"""Run until stop() is called."""

self._check_closed()

if self.is_running():

raise RuntimeError('This event loop is already running')

if events._get_running_loop() is not None:

raise RuntimeError(

'Cannot run the event loop while another loop is running')

self._set_coroutine_wrapper(self._debug)

self._thread_id = threading.get_ident()

if self._asyncgens is not None:

old_agen_hooks = sys.get_asyncgen_hooks()

sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,

finalizer=self._asyncgen_finalizer_hook)

try:

events._set_running_loop(self)

while True:

self._run_once()

if self._stopping:

break

finally:

self._stopping = False

self._thread_id = None

events._set_running_loop(None)

self._set_coroutine_wrapper(False)

if self._asyncgens is not None:

sys.set_asyncgen_hooks(*old_agen_hooks)

loop.run_forever() 先是检查是否有正在运行的事件循环, 保证同一时间只有一个loop运行,之后

try:

events._set_running_loop(self)

while True:

self._run_once()

if self._stopping:

break

可以看到是一直调用_run_once(),由于 _run_once()内容较多这里就不再贴完整的代码, 只摘抄关键的部分.

ntodo = len(self._ready)

for i in range(ntodo):

handle = self._ready.popleft()

if handle._cancelled:

continue

if self._debug:

pass # not care ...

else:

handle._run()

handle = None # Needed to break cycles when an exception occurs.

可以看出, 所有的call_soon遵循FIFO原则,不过这里还是会block的, 比如在前文中的hello_world中加入耗时的操作. 所以一旦想用异步,还是全部使用异步,要么0要么1.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值