【问题标题】:Where is the memory leak? How to timeout threads during multiprocessing in python?内存泄漏在哪里? python - 如何在python中的多处理期间使线程超时?
【发布时间】:2018-07-10 11:23:35
【问题描述】:

目前尚不清楚如何在 python 中正确超时 joblib 的 Parallel 的工作人员。其他人也有类似的问题herehereherehere

在我的示例中,我使用 50 个 joblib 工人池和 threading 后端。

并行调用(线程):

output = Parallel(n_jobs=50, backend  = 'threading')
    (delayed(get_output)(INPUT) 
        for INPUT in list)

这里,Parallellen(list) <= n_jobs 时立即挂起而没有错误,但仅在n_jobs => -1 时才挂起。

为了规避这个问题,人们向instructions 提供了如何使用multiprocessingParallel 函数(上例中的get_output(INPUT))创建超时装饰器:

主要功能(装饰):

@with_timeout(10)    # multiprocessing
def get_output(INPUT):     # threading
    output = do_stuff(INPUT)
    return output

多处理装饰器:

def with_timeout(timeout):
    def decorator(decorated):
        @functools.wraps(decorated)
        def inner(*args, **kwargs):
            pool = multiprocessing.pool.ThreadPool(1)
            async_result = pool.apply_async(decorated, args, kwargs)
            try:
                return async_result.get(timeout)
            except multiprocessing.TimeoutError:
                return
        return inner
    return decorator

将装饰器添加到原本可以工作的代码中会导致在约 2 倍超时长度加上 eclipse 崩溃后发生内存泄漏。

装饰器的泄漏点在哪里?

如何在 python 中的多处理期间使线程超时?

【问题讨论】:

  • 我是原来的OP。我的内部功能使用硒。对于 selenium 上下文,我找到了一种直接使内部函数超时的方法。根据您的情况,这可能/可能不适用 - 请告诉我,我会直接回答
  • 在我的帖子下回答。

标签: web-scraping screen-scraping python-multiprocessing python-multithreading joblib


【解决方案1】:

在没有hack 的情况下,无法在 Python 中终止线程。

您遇到的内存泄漏是由于您认为它们已被杀死的线程的积累。为了证明这一点,只需尝试检查您的应用程序正在运行的线程数量,您就会看到它们在缓慢增长。

在底层,ThreadPool 的线程并没有终止,而是一直运行你的函数直到结束。

线程不能被杀死的原因是线程与父进程共享内存。因此,在确保应用程序的内存完整性的同时杀死线程是非常困难的。

Java 开发人员想通了long ago

如果您可以在单独的进程中运行您的函数,那么您可以轻松地依赖超时逻辑,一旦达到超时,进程本身就会被终止。

Pebble 库已经提供了decorators with timeout

【讨论】:

  • 感谢您的意见。我尝试使用 Pebble 和其他各种装饰器来超时此功能(即 timeout-decorator 0.4.0)。总之,所有这些都会产生内存泄漏。与您的假设相反,这与超时线程的数量无关,因为在我什至没有看到超时线程的时间内内存使用量急剧增加。另一种解决方案是使用 SIGTERM 和 SIGALRM 但这在 Windows 中不起作用。我现在的解决方案是每 n 分钟重新启动整个代码,确保所有最终挂起的线程也重新启动。
  • 抱歉回复晚了。如果您的程序泄漏内存,您应该做的是确定泄漏的来源。您可以查看this 的帖子。如果您无法防止泄漏,我建议您在单独的进程中运行您的逻辑并通过resource 设施设置内存限制。与timeout 结合使用应该使您的服务足够健壮。
猜你喜欢
  • 2011-05-03
  • 2012-10-19
  • 2018-12-18
  • 2016-08-10
  • 2013-07-01
  • 1970-01-01
相关资源
最近更新 更多