首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用ThreadPoolExecutor阻塞所有线程的pow函数

使用ThreadPoolExecutor阻塞所有线程的pow函数
EN

Stack Overflow用户
提问于 2019-06-21 03:08:31
回答 2查看 183关注 0票数 1

尽管关于ThreadPoolExecutor的第一个示例使用了pow函数( https://docs.python.org/3/library/concurrent.futures.html ),但是使用pow似乎会在被调用时异常地阻塞所有线程。请参阅下面的代码。

代码语言:javascript
复制
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)

我期望得到的输出是:

代码语言:javascript
复制
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

但是程序在“启动电源...”之后停止运行。给出结果:

代码语言:javascript
复制
block 1
non 1
block 2
non 2
block 3
non 3
block 4
Starting pow....
EN

回答 2

Stack Overflow用户

发布于 2019-06-21 03:20:57

这是因为Python的全局解释器锁(GIL)。

如果您查看函数的字节码:

代码语言:javascript
复制
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)

它看起来像这样:

代码语言:javascript
复制
  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)需要很长时间才能执行,所以另一个线程在执行期间没有机会运行。

票数 1
EN

Stack Overflow用户

发布于 2019-06-21 03:10:57

代码语言:javascript
复制
pow(363,100000000000000)

如果一个大的计算量。它需要时间来处理并给出结果。

简单的计算:

代码语言:javascript
复制
>>> 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)

时间呈指数增长

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56692439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档