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

Where is the memory leak? How to timeout threads during multiprocessing in python?

目前尚不清楚如何正确地使 python 中 joblib 的 Parallel 的工作线程超时。其他人也有类似的问题 here, here, here and here

在我的示例中,我使用了 50 个 joblib worker 和 threading 后端。

并行调用(线程):

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

在这里,Parallellen(list) <= n_jobs 时挂起且没有错误,但仅在 n_jobs => -1.

时挂起

为了规避这个问题,人们给出instructions如何使用[=22为Parallel函数(上例中的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 中的多处理期间使线程超时?

如果没有 hack,则无法在 Python 中终止线程。

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

在幕后,ThreadPool 的线程不会终止,但会 运行ning 您的函数直到结束。

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

Java 开发人员想通了 long ago

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

Pebble library already offers decorators with timeout.