代码之家  ›  专栏  ›  技术社区  ›  sudonym

内存泄漏在哪里?如何在python中的多处理过程中超时线程?

  •  11
  • sudonym  · 技术社区  · 7 年前

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

    在我的示例中,我使用了一个50人的池 joblib 具有 threading 后端。

    并行调用(线程):

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

    在这里 平行的 挂起时无错误 len(list) <= n_jobs 但只有当 n_jobs => -1 .

    为了避免这个问题,人们 instructions 关于如何为 平行的 功能( get_output(INPUT) )在上述示例中)使用 multiprocessing :

    主要功能(装饰):

    @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
    

    将decorator添加到其他工作代码中会导致内存泄漏,超过超时时间的2倍,再加上eclipse崩溃。

    装修工的漏洞在哪里?

    如何在python中的多处理过程中超时线程?

    1 回复  |  直到 7 年前
        1
  •  10
  •   noxdafox    7 年前

    在Python中,如果没有 hack .

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

    在引擎盖下 ThreadPool 不会终止,但会一直运行函数直到结束。

    无法终止线程的原因是线程与父进程共享内存。因此,很难在确保应用程序内存完整性的同时终止线程。

    Java开发人员解决了这个问题 long ago .

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

    这个 Pebble 库已提供 decorators with timeout .