Python ThreadPoolExecutor 如何在并发线程之间切换?
在异步/等待事件循环的情况下,不同代码片段之间的切换发生在等待调用时。 ThreadPoolExecutor 是否运行每个提交的任务一段随机的时间> 或者直到某个地方调用 Thread.sleep() ?或者操作系统临时切换去做其他事情,线程被迫释放 GIL,从而允许其他线程下次获取 GIL?
ThreadPoolExecutor 是否运行每个提交的任务随机的时间?
不。执行器运行一个带有工作队列的线程池。当您添加新任务时,线程将拾取它并运行它直至完成。在前一个任务完成之前,各个线程不会切换任务。
只要全局解释器锁(GIL)仍然存在,在任何给定时刻只有一个线程可以执行Python字节码(在一个进程内;不包括多个子解释器)。 自 Python-3.2 起,GIL 每 5 毫秒切换一次线程(可配置),而不是像以前那样每 100 条指令切换一次。为了进行比较,Linux 内核每 1、3 或 10 毫秒运行一次调度程序,其中 1 毫秒是桌面发行版的默认值。
或者直到某个地方调用 Thread.sleep()?每个可能阻塞/睡眠的系统调用以及每个可能长时间运行的已编译代码的调用通常都被写入
释放GIL。使用新的 GIL,优先级机制允许此类线程快速重新获取锁,这对于诸如 read()
之类的系统调用非常有用,这些系统调用通常返回非常快,并受益于返回的数据很快被处理。
或者操作系统临时切换去做其他事情,线程被迫释放 GIL,从而允许其他线程下次获取 GIL?操作系统不知道 GIL。如果操作系统中断 python 进程,则当前持有 GIL 的任何线程都将继续持有它。在此期间没有其他线程可以获取它。