共享内存
异步调度器接受任何 concurrent.futures.Executor
实例。这包括 Python 标准库中定义的 ThreadPoolExecutor
和 ProcessPoolExecutor
实例,以及任何第三方库中的子类。Dask 还定义了自己的 SynchronousExecutor
,它只是简单地在主线程上运行函数(对调试有用)。
完整的 dask get
函数分别存在于 dask.threaded.get
、dask.multiprocessing.get
和 dask.get
中。
政策
异步调度器维护着索引数据结构,这些结构显示了哪些任务依赖于哪些数据,哪些数据是可用的,哪些数据在等待哪些任务完成之前无法释放,以及哪些任务当前正在运行。它可以在常数时间内相对于总任务数和可用任务数更新这些索引结构。这些索引结构使得dask异步调度器能够在单台机器上扩展到非常多的任务。
为了保持内存占用小,我们选择将准备运行的任务保存在一个后进先出的栈中,这样最新可用的任务会优先执行。这鼓励在开始新的任务链之前完成相关的任务链。这也可以在常数时间内查询。
已知限制
共享内存调度器有一些显著的限制:
它在单台机器上运行
线程调度器受限于 Python 代码的 GIL,因此如果你的操作是纯 Python 函数,你不应该期望多核加速。
多进程调度器必须在工作者之间序列化函数,这可能会失败
多进程调度器必须在工作者和中央进程之间序列化数据,这可能会很耗费资源。
多进程调度器无法直接在工作者进程之间传输数据;所有数据都通过主进程路由。