【问题标题】:Checking up on a `concurrent.futures.ThreadPoolExecutor`检查`concurrent.futures.ThreadPoolExecutor`
【发布时间】:2014-10-17 21:54:08
【问题描述】:

我有一个直播concurrent.futures.ThreadPoolExecutor。我想检查它的状态。我想知道有多少线程,有多少正在处理任务,哪些任务,有多少是空闲的,哪些任务在队列中。我怎样才能找到这些东西?

【问题讨论】:

标签: python concurrency introspection concurrent.futures


【解决方案1】:

池和待处理的工作项队列有一些可见性。要找出可用的内容,请打印 poolx.__dict__ 以查看结构。阅读ThreadPool代码,还不错:concurrent.futures.thread

以下创建一个带有一个线程的池。然后它会创建两个作业:一个休眠 3 秒,另一个立即返回。然后打印池中待处理工作项的数量。

之后,我们打印出工作队列中的项目。在这种情况下,一个线程已经在执行time.sleep(3) 函数,所以它不在队列中。打印带有 args [0] 和 kwargs {} 的函数 sleep,因为这是池要运行的下一个工作项。

感谢@dano 对非破坏性队列的洞察力,以及@abarnert。

来源

import concurrent.futures, time

poolx = concurrent.futures.ThreadPoolExecutor(max_workers=1)
poolx.submit(time.sleep, 3)
poolx.submit(time.sleep, 0)   # very fast

print('pending:', poolx._work_queue.qsize(), 'jobs')
print('threads:', len(poolx._threads))
print()

# TODO: make thread safe; work on copy of queue?
print('Estimated Pending Work Queue:')
for num,item in enumerate(poolx._work_queue.queue):
    print('{}\t{}\t{}\t{}'.format(
        num+1, item.fn, item.args, item.kwargs,
        ))

poolx.shutdown(wait=False)

输出

pending: 1 jobs
threads: 1

Pending Work Queue:
1   <built-in function sleep>   (0,)    {}

【讨论】:

  • 您可以在不破坏队列的情况下检查队列中的内容:for item in poolx._work_queue.queue: print(item.fn, item.args, item.kwargs)
  • 再次感谢@dano -- 我已经更新了代码和描述以添加您的见解。
  • 这不是线程安全的。 pool._work_queue 部分很好,但迭代 pool._work_queue.queue 不是。该队列成员仅应与适当的同步一起使用;您的迭代器可能在任何时候被另一个线程推送或弹出无效。您可能通常在 CPython 中的低争用场景中侥幸逃脱,但使用无 GIL 实现或高争用(即,正是您真正需要队列的情况)它会失败.
  • 似乎获取队列大小至少应该是安全的,这足以回答大约 75% 的问题...但是要知道排队的是什么,您确实需要明确地将其安全地交给它-iterable 队列,不使用 queue.Queue 中的那个。
  • @abarnert 我想你可以在迭代之前获取pool._work_queue.mutex。这就是queue.Queue 用于同步的全部内容。
【解决方案2】:

找到pending 期货也不是非常干净可靠的方法,但我这样做:

if 'state=pending' in str(future):
    logger.debug('PENDING')
elif future.running():
    logger.debug('RUNNING')
elif future.cancelled():
    logger.debug('CANCELLED')
elif future.exception():
    logger.debug('EXCEPTION')
elif future.done():
    logger.debug('DONE')

【讨论】:

    猜你喜欢
    • 2017-12-12
    • 1970-01-01
    • 2022-11-02
    • 2019-07-13
    • 2018-08-25
    • 2015-08-03
    • 2021-10-09
    • 2014-02-04
    • 2019-11-14
    相关资源
    最近更新 更多