[求教] 协程与 IO 多路复用区别? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
kaiser1992
V2EX    Python

[求教] 协程与 IO 多路复用区别?

  •  
  •   kaiser1992 2020-07-17 13:35:36 +08:00 5142 次点击
    这是一个创建于 1925 天前的主题,其中的信息可能已经有所发展或是发生改变。
    网上搜索 python asyncio 包的介绍,清一色都涉及到了 IO 多路复用( EventLoop ),非阻塞确实能够提升性能,但是和协程有啥关系呢~?

    我的疑惑是 python 的原生协程是基于生成器增强来实现的,怎么与 IO 多路复用关联到一块呢?
    14 条回复    2020-11-03 13:50:10 +08:00
    reus
        1
    reus  
       2020-07-17 14:29:54 +08:00 via Android
    建议不要理会也不要使用“多路复用”、“非阻塞”、“协程”这些词,因为不同人会有不同的理解,而且没法达成一致。
    ruanimal
        2
    ruanimal  
       2020-07-17 14:34:49 +08:00
    协程只是让 eventloop 写起来更方便,不然你得写回调。

    eventloop 必须非阻塞的 fd 加多路复用
    chevalier
        3
    chevalier  
       2020-07-17 14:39:46 +08:00
    都学过操作系统,操作系统的功能之一就是提供硬件的访问接口,例如:网络 IO

    协程是“用户态”的概念,IO 多路复用是系统调用的接口,是“用户态”与“内核态”交互的方式;毕竟协程是无法直接访问网卡缓冲区的,需要调用系统接口来获取网络 IO 的数据。

    所以网络程序,协程一般需要搭配 IO 多路复用才能发挥最大威力,协程提升并发处理的能力,网络 IO 能力就要靠 IO 多路复用。

    说得比较简单,细说了能写好几篇文章了。建议看看 tornado/asyncio 的源码,网络通信模块,或者自己用 C 写一写 epoll 系统调用,就容易理解了。
    coldmonkeybit
        4
    coldmonkeybit  
       2020-07-17 15:07:02 +08:00
    借楼请教,没用过 Python,请问 python 中的协程跟 go 的协程类似么?
    kaiser1992
        5
    kaiser1992  
    OP
       2020-07-17 18:34:54 +08:00
    @chevalier 所以说,如果我的程序一点没有 IO,协程执行过程中就不会用到多路复用的机制了吧~?
    palfortime
        6
    palfortime  
       2020-07-17 20:02:33 +08:00 via Android
    协程和 io 多路复用是两个维度的东西,协程只要有 io 就可以派上用途,线程也可以搭配 io 多路复用。
    guochao
        7
    guochao  
       2020-07-17 22:53:35 +08:00
    > 如果我的程序一点没有 IO,协程执行过程中就不会用到多路复用的机制了吧~?

    对,如果一个程序没有 IO 和其他暂停线程的手段,也就是说是《计算密集型》的程序,那么就和多路复用无关,毕竟这是个 IO 概念。

    协程的本质是利用多路复用和信号尽可能多的《在同一个线程上跑更多的任务》,IO 和休眠的时候协程就会暂停,遇到信号就会唤醒。无非就是把以前的回调换了一种形式,让回调变成顺序的过程,更适合人类理解。

    《 IO 密集型》的程序利用协程可以获取《更高的并发度(同一个线程上可以跑更多的 IO 任务)》,但是也会带来《更高的延迟(唤醒和调度的开销)》。计算密集型的程序几乎不会有任何提升。
    dongcidaci
        8
    dongcidaci  
       2020-07-18 06:22:51 +08:00 via Android
    斗胆说一下,协程就是用户态的线程,上下文切换开销小。多路复用是一种 IO 方式。貌似没什么关系。
    ysc3839
        9
    ysc3839  
       2020-07-18 10:10:38 +08:00 via Android
    推荐看一下这篇文章 https://blog.panicsoftware.com/coroutines-introduction/

    我个人的理解,无栈协程是一种可以中途返回,后面再从之前返回的地方恢复执行的函数。利用这种特性可以实现许多功能,比如生成器,求出一个值之后返回,需要下一个值的时候再恢复执行。或者用来编写异步 IO 代码,在开始 IO 操作后返回,IO 操作完成之后恢复执行。
    而异步 IO 又有多种实现方式。可以用最简单的多线程来实现,协程启动一个新线程来进行阻塞 IO 操作,同时返回,新线程中的 IO 操作完成后,在新线程中恢复执行协程。
    也可以用单线程来实现,但是要配合 IO 多路复用来实现,IO 多路复用简单说是同时监视多个文件描述符是否就绪,协程在当前线程进行非阻塞的 IO 操作之后返回,然后当前线程会检测文件描述符是否就绪,就绪后恢复执行协程。
    ysc3839
        10
    ysc3839  
       2020-07-18 10:15:56 +08:00 via Android
    总结起来是,协程跟 IO 多路复用关系不大,因为完全可以用协程写一个不涉及 IO 操作的代码,即使涉及到了 IO 操作,也可以使用多线程的模型。
    Python 的 asyncio 选择了单线程+IO 多路复用的模型,所以相关资料都会涉及,但是 asyncio 并不等同于协程。
    irosyking
        11
    irosyking  
       2020-07-20 17:28:03 +08:00   1
    1 、Async IO Framework = eventloop + non-blocking sockets + coroutines
    Async IO Framework = eventloop + non-blocking sockets + callbacks

    2 、Coroutine = Future + Task + Generator
    Lazy computation = Generator
    Marinej
        12
    Marinej  
       2020-07-21 10:02:11 +08:00
    协程就是单线程的调度,有了 IO 多路复用,epoll 这种技术,协程在 IO 密集型任务上才能发光发热,没有 IO 多路复用,协程也是白给
    ychost
        13
    ychost  
       2020-07-27 16:03:58 +08:00
    IO 复用 是系统层面的词语(操作系统级别支持,epoll 之类的),协程是软件层面的支持,比如 go 语言支持协程,kotlin 的协议是通过一个线程去轮询轻量的任务实现的,所以无法锁协程,只能锁协程外面的那根线程
    fasionchan
        14
    fasionchan  
       2020-11-03 13:50:10 +08:00   1
    简单说,IO 多路复用是高效的底层功能,但非阻塞的编程模型回调函数满天飞,并不直观。而协程是对 IO 多路复用的抽象封装,让你可以用阻塞的编程模型编写非阻塞的代码,解决回调满天飞的弊端。

    我基于 epoll 实现了一个极简的协程库,仅仅只有 100 多行代码,有需要可以参考下:

    https://mp.weixin.qq.com/s/MaLMf3HZCYfmzxOY1QfPnw

    麻雀虽小,五脏俱全。关于 IO 多路复用与协程的关系,以及协程的实现原理,一下子就清晰了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5194 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 07:21 PVG 15:21 LAX 00:21 JFK 03:21
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86