【问题标题】:Are coroutines single-threaded by nature?协程本质上是单线程的吗?
【发布时间】:2022-01-23 13:42:59
【问题描述】:
根据Wikipedia,协程基于协作多任务处理,这使得它们比线程消耗更少的资源。没有上下文切换、没有阻塞、没有昂贵的系统调用、没有临界区等等。
换句话说,所有这些协程的好处似乎都来自于一开始就禁止多线程。这使得协程本质上是单线程的:实现了并发,但没有真正的并行。
这是真的吗?是否可以改用多线程来实现协程?
【问题讨论】:
标签:
multithreading
concurrency
operating-system
coroutine
【解决方案1】:
协程允许在没有多线程的情况下进行多任务处理,但它们不会禁止多线程。
在同时支持这两者的语言中,处于睡眠状态的协程可以在不同的线程中重新唤醒。
CPU 密集型任务的通常安排是拥有一个线程池,其线程数大约是 CPU 内核数的两倍。然后使用该线程池同时执行可能数千个协程。线程共享一个准备执行的协程队列,当一个线程当前的协程阻塞时,它只会从队列中获取另一个协程来处理。
在这种情况下,您有足够的繁忙线程来保持 CPU 繁忙,并且您仍然有线程上下文切换,但它们的数量不足以浪费大量资源。协程上下文切换的次数要高出数千倍。
【讨论】:
-
有趣。所以 1) 协程可以被视为原始线程的语法糖吗?另外,2)由于您提到的实现使用线程,协程可能提供并发(与Wikipedia says相反)?
【解决方案2】:
多个协程可以映射到单个操作系统线程。但是单个操作系统线程只能使用 1 个 CPU。所以你需要多个操作系统线程来利用多个 CPU。
因此,如果协程调度程序需要使用多个 CPU(很可能),它需要使用多个操作系统线程。
查看 Go scheduler 并查找 MN 调度程序。