1
reus 2020-07-17 14:29:54 +08:00 via Android
建议不要理会也不要使用“多路复用”、“非阻塞”、“协程”这些词,因为不同人会有不同的理解,而且没法达成一致。
|
2
ruanimal 2020-07-17 14:34:49 +08:00
协程只是让 eventloop 写起来更方便,不然你得写回调。
eventloop 必须非阻塞的 fd 加多路复用 |
3
chevalier 2020-07-17 14:39:46 +08:00
都学过操作系统,操作系统的功能之一就是提供硬件的访问接口,例如:网络 IO
协程是“用户态”的概念,IO 多路复用是系统调用的接口,是“用户态”与“内核态”交互的方式;毕竟协程是无法直接访问网卡缓冲区的,需要调用系统接口来获取网络 IO 的数据。 所以网络程序,协程一般需要搭配 IO 多路复用才能发挥最大威力,协程提升并发处理的能力,网络 IO 能力就要靠 IO 多路复用。 说得比较简单,细说了能写好几篇文章了。建议看看 tornado/asyncio 的源码,网络通信模块,或者自己用 C 写一写 epoll 系统调用,就容易理解了。 |
4
coldmonkeybit 2020-07-17 15:07:02 +08:00
借楼请教,没用过 Python,请问 python 中的协程跟 go 的协程类似么?
|
5
kaiser1992 OP @chevalier 所以说,如果我的程序一点没有 IO,协程执行过程中就不会用到多路复用的机制了吧~?
|
6
palfortime 2020-07-17 20:02:33 +08:00 via Android
协程和 io 多路复用是两个维度的东西,协程只要有 io 就可以派上用途,线程也可以搭配 io 多路复用。
|
7
guochao 2020-07-17 22:53:35 +08:00
> 如果我的程序一点没有 IO,协程执行过程中就不会用到多路复用的机制了吧~?
对,如果一个程序没有 IO 和其他暂停线程的手段,也就是说是《计算密集型》的程序,那么就和多路复用无关,毕竟这是个 IO 概念。 协程的本质是利用多路复用和信号尽可能多的《在同一个线程上跑更多的任务》,IO 和休眠的时候协程就会暂停,遇到信号就会唤醒。无非就是把以前的回调换了一种形式,让回调变成顺序的过程,更适合人类理解。 《 IO 密集型》的程序利用协程可以获取《更高的并发度(同一个线程上可以跑更多的 IO 任务)》,但是也会带来《更高的延迟(唤醒和调度的开销)》。计算密集型的程序几乎不会有任何提升。 |
8
dongcidaci 2020-07-18 06:22:51 +08:00 via Android
斗胆说一下,协程就是用户态的线程,上下文切换开销小。多路复用是一种 IO 方式。貌似没什么关系。
|
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 操作之后返回,然后当前线程会检测文件描述符是否就绪,就绪后恢复执行协程。 |
10
ysc3839 2020-07-18 10:15:56 +08:00 via Android
总结起来是,协程跟 IO 多路复用关系不大,因为完全可以用协程写一个不涉及 IO 操作的代码,即使涉及到了 IO 操作,也可以使用多线程的模型。
Python 的 asyncio 选择了单线程+IO 多路复用的模型,所以相关资料都会涉及,但是 asyncio 并不等同于协程。 |
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 |
12
Marinej 2020-07-21 10:02:11 +08:00
协程就是单线程的调度,有了 IO 多路复用,epoll 这种技术,协程在 IO 密集型任务上才能发光发热,没有 IO 多路复用,协程也是白给
|
13
ychost 2020-07-27 16:03:58 +08:00
IO 复用 是系统层面的词语(操作系统级别支持,epoll 之类的),协程是软件层面的支持,比如 go 语言支持协程,kotlin 的协议是通过一个线程去轮询轻量的任务实现的,所以无法锁协程,只能锁协程外面的那根线程
|
14
fasionchan 2020-11-03 13:50:10 +08:00 1
简单说,IO 多路复用是高效的底层功能,但非阻塞的编程模型回调函数满天飞,并不直观。而协程是对 IO 多路复用的抽象封装,让你可以用阻塞的编程模型编写非阻塞的代码,解决回调满天飞的弊端。
我基于 epoll 实现了一个极简的协程库,仅仅只有 100 多行代码,有需要可以参考下: https://mp.weixin.qq.com/s/MaLMf3HZCYfmzxOY1QfPnw 麻雀虽小,五脏俱全。关于 IO 多路复用与协程的关系,以及协程的实现原理,一下子就清晰了。 |