python - 为什么 python 的 ThreadPoolExecutor 工作队列似乎接受的项目超过了它的最大工作人员?
问题描述
import time
from concurrent.futures import ThreadPoolExecutor
class Sandbox:
def __init__(self, n=5):
self.n = n
self.executor = ThreadPoolExecutor(n)
def make_request(self):
if self.executor._work_queue.qsize() < self.n:
self.executor.submit(self.do_something_that_takes_long)
print('HTTP_202')
else:
print('HTTP_429')
def do_something_that_takes_long(self):
time.sleep(10)
def do_ok_situation():
s = Sandbox()
for _ in range(5):
s.make_request()
def do_bad_situation():
s = Sandbox()
for _ in range(100):
s.make_request()
# do_ok_situation()
do_bad_situation()
这将输出
HTTP_202
HTTP_202
HTTP_202
HTTP_202
HTTP_202
HTTP_202
HTTP_202
HTTP_202
HTTP_202
HTTP_202
HTTP_429
HTTP_429
HTTP_429
HTTP_429
...
此代码将输出 10 个 HTTP_200(在我的机器上)而不是 5 个。我希望我向执行程序发出的请求数等于放入线程执行程序队列的作业数。
为什么会这样?如何将此数字限制为最大工作人员的数量?
解决方案
似乎self.executor._work_queue.qsize()
返回work_queue
等待线程执行它们的请求数。但是,当您调用时submit()
,线程池中通常有一个空闲线程可以立即处理请求,因此对于前五次调用make_request()
,请求根本不会进入work_queue
,而是直接交给线程执行。
您可以通过添加如下行来向自己展示这种行为
print("qSize=%i"%self.executor._work_queue.qsize())
make_request()
在你的方法的前面;您会看到qSize
前 5 次调用仍然为 0,并且只有在 ThreadPool 中的所有 5 个线程都已忙于执行something_that_takes_long
并且因此其他请求进入队列后才开始变大。
推荐阅读
- android - 使用 kotliin 更改背景色调
- javascript - 我如何使用 Joi 有效函数并允许小写和大写字母
- html - 两列布局中不同大小的弹性项目之间不需要的空间
- javascript - JEST TypeError:无法读取未定义的属性“json”
- c++ - _CRTDBG_MAP_ALLOC - 如何排除堆栈对象
- python-3.x - 如果服务器名称来自 input(),则无法连接到 SQL 实例
- sql - 多列计数和聚合
- html - 如何将 Font Awesome 添加到我的项目中,以便正确显示图标?
- angular - 我得到 Function CollectionReference.doc() 需要它的第一个参数是非空字符串类型,但它是:对象错误
- python - Python 2 和 Python 3 内置 all() 函数的行为不同