为什么线程dask示例并行执行

Why is threaded dask example executing in parallel

出于教学目的,我正在尝试使用 dask delayed 创建简单的示例,这些示例在使用线程而不是进程时突出显示 GIL。我现在使用单机调度程序来保持简单。我的理解是从单线程切换到线程不会有任何变化,因为 GIL 应该阻止并行执行。

事实并非如此。当我使用 threaded 选项时,代码仍然比 processes 运行得更快(实际上更快)(单线程=3s,线程=1s,进程=1.7s)。三个延时调用基本同时执行

显然我并不像我想的那样明白发生了什么。有人可以解释这里发生了什么吗?为什么 GIL 没有用线程锁定我的计算?

import time
import dask
from dask import delayed


def func(i):
    import time
    print(f'Function {i:.0f} starting')
    time.sleep(1)
    print(f'Function {i:.0f} finished')


lazy = [delayed(func)(i) for i in range(3)]
with dask.config.set(scheduler='processes'):  # single-threaded, processes or threads
    start = time.time()
    dask.compute(lazy)
    elaps = time.time() - start
    print(elaps)

答案很简单:sleep() 没有 GIL,因为没有什么可做的。您需要设计一些真正的 "work" 以锁定线程并降低并行性。