【问题标题】:How are threads (and asyncio tasks) scheduled in Python?如何在 Python 中调度线程(和异步任务)?
【发布时间】:2020-01-21 04:04:03
【问题描述】:
我正在尝试理解 Python 中的并发性,但我对如何安排线程以及如何安排任务(在 asyncio 库中)运行/等待感到困惑。
假设一个线程试图获取一个锁并被阻塞。 Python 解释器是否立即将该线程放入“阻塞”队列?这个被阻塞的线程如何恢复到运行状态?是否涉及忙等待?
当异步库中的任务(相当于线程)在异步互斥体上阻塞时,这有何不同?
如果上述两种情况都没有涉及到忙等待,那么 asyncio 的优势是什么?
【问题讨论】:
标签:
python
multithreading
mutex
python-asyncio
python-multithreading
【解决方案1】:
假设一个线程试图获取一个锁并被阻塞。 Python 解释器是否立即将该线程放入“阻塞”队列?
Python 创建真正的操作系统线程,因此解释器不需要进行排队或调度。
一个可能的例外是 global lock 被解释器用来序列化 Python 代码的执行和对 Python 对象的访问。此锁不仅在获取线程锁之前被释放,而且在任何(可能)阻塞操作之前释放,例如从 IO 句柄读取或休眠。
如果以上两种情况都不涉及忙等待,asyncio有什么好处?
优点是 asyncio 不需要为它并行执行的每个协程创建一个新的 OS 线程。操作系统线程很昂贵,而异步任务非常轻量级。此外,asyncio 使潜在的切换点可见(await 关键字),因此竞争条件的可能性较小。
您可以将 asyncio 视为 Twisted 的继承者,但具有现代 API 并使用可挂起的协程而不是显式回调链。