尽管关于 ThreadPoolExecutor 的第一个示例使用了 pow 函数(https://docs.python.org/3/library/concurrent.futures.html https://docs.python.org/3/library/concurrent.futures.html)似乎使用 pow 在调用时会异常阻塞所有线程。请参阅下面的代码。
from concurrent.futures import ThreadPoolExecutor
import time
executor = ThreadPoolExecutor(max_workers=16)
def blocking():
i = 0
while True:
time.sleep(1)
i+=1
print("block",i)
if i>3:
print("Starting pow....")
break
block= pow(363,100000000000000)
return True
def non_blocking():
i = 0
while True:
time.sleep(1)
i+=1
print("non",i)
return True
f1 = executor.submit(blocking)
f2 = executor.submit(non_blocking)
我期望的输出:
block 1
non 1
block 2
non 2
block 3
non 3
block 4
Starting pow....
non 4
non 5
non 6
non 7
non 8
但程序在“starting pow....”后停止运行,给出结果:
block 1
non 1
block 2
non 2
block 3
non 3
block 4
Starting pow....
你的Python实现(可能是CPython)必须有一个全局解释器锁 https://wiki.python.org/moin/GlobalInterpreterLock (GIL)
pow
是一个原生 Python 函数,它在调用时不会释放 GIL,从而在运行且运行相当长一段时间时有效地阻止所有执行。
如果你想要非阻塞,请使用ProcessPoolExecutor https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor反而。一个单独的进程意味着 2 个单独的 GIL 并且不会阻塞。它具有完全相同的界面。它也有更多的限制,因为它需要参数可腌制的(没有像线程那样方便的共享内存)
请注意,此计算可能永远不会结束或以“内存不足错误”结束:因为它是整数之间的幂big幂值,因此它不会像浮点数那样溢出,而是不断计算,每次创建越来越大的整数
该数字的估计位数大致为:
>>> math.log10(363)*100000000000000
255990662503611.25
10^14 位数字比当前任何计算机可以处理的内存和 CPU 数量都要多。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)