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

sud*_*nym 11 screen-scraping web-scraping python-multithreading joblib python-multiprocessing

目前还不清楚如何Parallel在python中正确地删除joblib的工作者.其他人在这里,这里,这里这里有类似的问题.

在我的例子中,我正在使用一个由50 joblib名工人组成的 threading后端池.

并行调用(线程):

output = Parallel(n_jobs=50, backend  = 'threading')
    (delayed(get_output)(INPUT) 
        for INPUT in list)
Run Code Online (Sandbox Code Playgroud)

在这里,Parallel挂起没有错误,len(list) <= n_jobs但只有在n_jobs => -1.

为了克服这个问题,人们给予 说明如何创建一个超时装饰的Parallel功能(get_output(INPUT)使用)在上面的例子)multiprocessing:

主要功能(装饰):

@with_timeout(10)    # multiprocessing
def get_output(INPUT):     # threading
    output = do_stuff(INPUT)
    return output
Run Code Online (Sandbox Code Playgroud)

多处理装饰器:

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
Run Code Online (Sandbox Code Playgroud)

将装饰器添加到其他工作代码会导致内存泄漏超过超时长度加上eclipse崩溃的2倍.

装饰者在哪里泄漏?

如何在python中进行多处理期间超时线程?

nox*_*fox 8

没有hack就不可能在Python中杀死一个Thread .

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

在引擎盖下,它的线程ThreadPool没有终止,但一直运行你的功能直到最后.

Thread无法被杀死的原因是由于线程与父进程共享内存.因此,在确保应用程序的内存完整性的同时杀死线程非常困难.

Java开发人员很久以前就发现了这一点.

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

Pebble库已经提供了具有超时的装饰器.