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 · 4632 次点击
    这是一个创建于 1572 天前的主题,其中的信息可能已经有所发展或是发生改变。
    网上搜索 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   ·   实用小工具   ·   2980 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:41 · PVG 22:41 · LAX 06:41 · JFK 09:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.