简体   繁体   English

如何监控python的concurrent.futures.ProcessPoolExecutor?

[英]How to monitor python's concurrent.futures.ProcessPoolExecutor?

We are using the ProcessPoolExecutor from concurrent.futures in a service that asynchronously receives requests, and does the actual, synchronous processing in the process pool. 我们在一个异步接收请求的服务中使用来自concurrent.futuresProcessPoolExecutor ,并在进程池中进行实际的同步处理。

Once we ran into the case that the process pool was exhausted, so new requests had to wait until some other processes were finished. 一旦我们遇到流程池耗尽的情况,那么新请求必须等到其他一些流程完成。

Is there a way to interrogate the process pool for its current usage? 有没有办法询问进程池的当前用法? That would allow us to monitor their state and do proper capacity planning. 这将使我们能够监控其状态并进行适当的容量规划。

If there isn't, is there any good alternative process pool implementation with an asynchronous interface that supports such monitoring/capacity planning? 如果没有,是否有任何良好的替代流程池实现与支持此类监控/容量规划的异步接口?

The simplest way would be to extend ProcessPoolExecutor with desired behaviour. 最简单的方法是使ProcessPoolExecutor扩展所需的行为。 The example below maintains stdlib interface and does not access implementation details: 以下示例维护stdlib接口,但不访问实现细节:

from concurrent.futures import ProcessPoolExecutor


class MyProcessPoolExecutor(ProcessPoolExecutor):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._running_workers = 0

    def submit(self, *args, **kwargs):
        future = super().submit(*args, **kwargs)
        self._running_workers += 1
        future.add_done_callback(self._worker_is_done)
        return future

    def _worker_is_done(self, future):
        self._running_workers -= 1

    def get_pool_usage(self):
        return self._running_workers

I have recently solved this question for myself in a slightly different way. 我最近以稍微不同的方式为自己解决了这个问题。 Simplified, here's what I did: 简化,这是我做的:

  • I keep track of pending futures externally in a set that is defined in the scope of my main loop. 我在我的主循环范围内定义的集合中跟踪外部未决期货。
  • I attach a callback to each future, and this callback is a closure over the set of futures, allowing it to remove the future from the set when done. 我附加一个回调到每个未来,这个回调是对期货集合的一个闭包,允许它在完成时从集合中移除未来。

So, given that done() is the actual callback function, defined elsewhere, the following is defined in the scope of my main loop: 因此,假设done()是在其他地方定义的实际回调函数,则在我的主循环范围内定义以下内容:

bag = set()

def make_callback(b):

    def callback(f):
        nonlocal b
        b.remove(f)
        done(f)

    return callback

For each future f which I submit to the ProcessPoolExecutor, I add the callback: 对于我提交给ProcessPoolExecutor的每个未来f ,我添加回调:

f.add_done_callback(make_callback(bag))

At any time, it's possible to see a list of pending and running futures by looking at the contents of bag , optionally filtered by the result of the future's running() method. 在任何时候,都可以通过查看bag的内容来查看待处理和正在运行的期货列表,可以选择使用future的running()方法的结果进行过滤。 Eg: 例如:

print(*bag, sep='\n')
print('running:', *(f for f in bag if f.running()))

For many straightforward use cases, a module-level set variable would probably work just as well as the closure. 对于许多简单的用例,模块级设置变量可能与闭包一样有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 Python 中的 concurrent.futures.ProcessPoolExecutor 中传递“锁”? - How to pass the “lock” in my concurrent.futures.ProcessPoolExecutor in Python? concurrent.futures.ProcessPoolExecutor() 中的共享变量 python - Shared variable in concurrent.futures.ProcessPoolExecutor() python python concurrent.futures.ProcessPoolExecutor:.submit()vs .map()的性能 - python concurrent.futures.ProcessPoolExecutor: Performance of .submit() vs .map() Python concurrent.futures.ProcessPoolExecutor:大量 RAM 用于大量任务 - Python concurrent.futures.ProcessPoolExecutor: Lot of RAM for large number of tasks Python 3.8 - concurrent.futures.ProcessPoolExecutor 性能及时下降 - Python 3.8 - concurrent.futures.ProcessPoolExecutor performance going down in time 如何使用 asyncio 和 concurrent.futures.ProcessPoolExecutor 在 Python 中终止长时间运行的计算(CPU 绑定任务)? - How to terminate long-running computation (CPU bound task) in Python using asyncio and concurrent.futures.ProcessPoolExecutor? 如何从 concurrent.futures.ProcessPoolExecutor() 的结果生成数据帧? - How to generate a dataframe from the results of a concurrent.futures.ProcessPoolExecutor()? 如何使用不同的功能调用 concurrent.futures.ProcessPoolExecutor map - how to call concurrent.futures.ProcessPoolExecutor map with different functions 如何将 Popen 对象传递给 concurrent.futures.ProcessPoolExecutor - How to pass Popen objects to concurrent.futures.ProcessPoolExecutor 将带有对象的 function 传递到 concurrent.futures.ProcessPoolExecutor()? - Pass function with objects into concurrent.futures.ProcessPoolExecutor()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM