最近在学习 python 的 asyncio 库,但是有很多的疑问无法得到解答。
在《流畅的 python 》中有一个例子,出租车的离散事件仿真,它是用一个主循环调度几个协程,利用优先级队列来调度,但是每一次的运行时间(利用这个运行时间来模拟 IO 需要的时间)是在主循环中计算的。
关于上面那个例子可以参照这里: https://segmentfault.com/a/1190000009798067
那么我的第一个问题是:
我用类似上面的思想来理解 asyncio,也就是有一个队列,主循环会不停地从队列里取出下一个要做的事。当遇到了 IO,我们怎么知道 IO 的时间呢?不知道 IO 的时间我们怎么去排定它的运行时间并把它放进队列里呢?
还是说这样理解,IO 是系统调用,理解为不在我们的线程里运行了,当系统 IO 结束了它会自动把运行完的事件加到队列中?这样我们就从队列里知道 IO 完了又开心地回到刚才进行 IO 操作的那个协程里去了?
...可是我们是怎么控制系统调用把完成时的事件放到队列中呢...还必须是与 python 兼容的格式...而且系统调用我们应该是无法控制的啊...
还是说其实得到系统调用返回的结果其实很简单...有人能写一下代码示意一下吗?因为我一直不知道系统完成 IO 的通知应该通知到我们代码的哪一行里面。
第二个问题:
由此我引发了对其他异步的思考...比如 JavaScript 是单线程的,那么它其实就是一个事件循环是吗?会不断地从队列里取出下一次要做的事情。比如鼠标点击就会把点击的事件加到队列中,然后 js 从中拿到事件,调用对应的回调函数。那么也就是说 JavaScript 的单线程也只能处理“响应的部分”,而鼠标点击这个事件的捕捉是系统做的。虽然 JavaScript 的运行是单线程的,但是是需要多个线程的配合才能完成复杂的交互操作是吗?
最后一个问题:
如果我上面说的和 python 事件循环的原理类似,那么假设我要怎么把系统的通知放到队列中?比如我现在读一个文件,文件读取完毕的通知我怎么把它包装成符合 python 的形式放到队列中?而且是异步,这时我们在执行别的代码,通知会跑到哪里去呢?比如我要把它组装成一个 namedtuple event(name='read_down')
,然后把它放到我们已经定义了的队列中呢?有大神能帮忙写一下吗...
只学了两个月,很多理解不到位,希望大神指教。
1
wwqgtxx 2018-06-23 03:25:11 +08:00 via iPhone
可异步的系统调用肯定会有一个句柄可以通过类似于 wait 的调用来等待其完成,而这一类的句柄可以通过一种类似于 select 的调用批量监听,系统会在其中一个句柄有状态更新的时候返回
其实学 asyncio 最好的办法就是直接读 asyncio 的源代码,其中大部分模块都是 python 写的,所以并不难看懂 |