尽管关于ThreadPoolExecutor的第一个示例使用了pow函数( 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
但是程序在“启动电源...”之后停止运行。给出结果:
block 1
non 1
block 2
non 2
block 3
non 3
block 4
Starting pow....
发布于 2019-06-21 03:20:57
这是因为Python的全局解释器锁(GIL)。
如果您查看函数的字节码:
import time
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
import dis
dis.dis(blocking)
它看起来像这样:
4 0 LOAD_CONST 1 (0)
2 STORE_FAST 0 (i)
5 4 SETUP_LOOP 50 (to 56)
6 >> 6 LOAD_GLOBAL 0 (time)
8 LOAD_METHOD 1 (sleep)
10 LOAD_CONST 2 (1)
12 CALL_METHOD 1
14 POP_TOP
7 16 LOAD_FAST 0 (i)
18 LOAD_CONST 2 (1)
20 INPLACE_ADD
22 STORE_FAST 0 (i)
8 24 LOAD_GLOBAL 2 (print)
26 LOAD_CONST 3 ('block')
28 LOAD_FAST 0 (i)
30 CALL_FUNCTION 2
32 POP_TOP
9 34 LOAD_FAST 0 (i)
36 LOAD_CONST 4 (3)
38 COMPARE_OP 4 (>)
40 POP_JUMP_IF_FALSE 6
10 42 LOAD_GLOBAL 2 (print)
44 LOAD_CONST 5 ('Starting pow....')
46 CALL_FUNCTION 1
48 POP_TOP
11 50 BREAK_LOOP
52 JUMP_ABSOLUTE 6
54 POP_BLOCK
12 >> 56 LOAD_GLOBAL 3 (pow)
58 LOAD_CONST 6 (363)
60 LOAD_CONST 7 (100000000000000)
62 CALL_FUNCTION 2
64 STORE_FAST 1 (block)
13 66 LOAD_CONST 8 (True)
68 RETURN_VALUE
您将注意到,pow
调用在第62位作为单个字节码指令发生。GIL只能在字节码之间传递,所以由于pow(363,100000000000000)
需要很长时间才能执行,所以另一个线程在执行期间没有机会运行。
发布于 2019-06-21 03:10:57
pow(363,100000000000000)
如果一个大的计算量。它需要时间来处理并给出结果。
简单的计算:
>>> import time
>>> def test(power):
... start = time.time()
... pow(363, power)
... return time.time() - start
...
>>> for power in range(1,11):
... print(test(pow(10, power)))
...
6.198883056640625e-06
2.1457672119140625e-06
3.0517578125e-05
0.0009307861328125
0.0421295166015625
1.7541508674621582 #This is a (363, 1000000)
时间呈指数增长
https://stackoverflow.com/questions/56692439
复制相似问题