Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python进程池,每个进程超时,而不是池的所有进程_Python_Timeout_Multiprocessing_Pool - Fatal编程技术网

python进程池,每个进程超时,而不是池的所有进程

python进程池,每个进程超时,而不是池的所有进程,python,timeout,multiprocessing,pool,Python,Timeout,Multiprocessing,Pool,我需要运行许多进程,但不是全部一起运行,例如同时运行4个进程多处理。池正是我需要的。但问题是,如果进程持续时间超过超时时间(例如3秒),我需要终止该进程池只支持所有进程(而不是每个进程)等待超时。这就是我需要的: def f(): process_but_kill_if_it_takes_more_than_3_sec() pool.map(f, inputs) 我找不到一个简单的方法来使用池超时。这是伊莱·本德斯基写的。它是一个通过Thread.join(timeout)限制任意函数

我需要运行许多进程,但不是全部一起运行,例如同时运行4个进程<代码>多处理。池正是我需要的。但问题是,如果进程持续时间超过超时时间(例如3秒),我需要终止该进程<代码>池只支持所有进程(而不是每个进程)等待超时。这就是我需要的:

def f():
    process_but_kill_if_it_takes_more_than_3_sec()
pool.map(f, inputs)
我找不到一个简单的方法来使用
超时。这是伊莱·本德斯基写的。它是一个通过
Thread.join(timeout)
限制任意函数执行时间的函数。它是有效的,(尽管它的停止方法不起作用)。但这个方法在进程的主线程正在等待时运行一个新的不必要的线程,因为我们需要一个超时控制器。应该可以从一个点控制所有超时,如下所示:

import time
from multiprocessing import Process


def f(n):
    time.sleep(n)

timeout = 3
tasks = [1, 2, 4, 1, 8, 2]

procs = []
pool_len = 4
while len(tasks) > 0 or len(procs) > 0:
    if len(tasks) > 0 and len(procs) < pool_len:
        n = tasks.pop(0)
        p = Process(target=f, args=(n,))
        p.start()
        procs.append({'n': n, 'p': p, 't': time.time() + timeout})
    for d in procs:
        if not d['p'].is_alive():
            procs.remove(d)
            print '%s finished' % d['n']
        elif d['t'] < time.time():
            d['p'].terminate()
            procs.remove(d)
            print '%s killed' % d['n']
    time.sleep(0.05)
问题:有没有一种方法可以使用Pool来解决这个问题?

您可以使
f(n)
协作,以便它总是在超时时间内完成(如在GUI/网络事件处理程序中)

如果您不能使其合作,那么唯一可靠的选择是终止运行该函数的进程:

import multiprocessing as mp

def run_with_timeout(timeout, func, *args):
    receive_end, send_end = mp.Pipe(duplex=False)
    p = mp.Process(target=func, args=args, kwargs=dict(send_end=send_end))
    p.daemon = True
    p.start()
    send_end.close() # child must be the only one with it opened
    p.join(timeout)
    if p.is_alive():
        ####debug('%s timeout', args)
        p.terminate()
    else:
        return receive_end.recv()  # get value from the child
缺点是它要求每个函数调用都有一个新的进程(
maxstasksperchild=1
Pool的模拟)

使用线程池可以轻松地同时运行4个进程:

输出 小心:可能会有;您可以使用fork服务器进程来解决这些问题

import multiprocessing as mp

def run_with_timeout(timeout, func, *args):
    receive_end, send_end = mp.Pipe(duplex=False)
    p = mp.Process(target=func, args=args, kwargs=dict(send_end=send_end))
    p.daemon = True
    p.start()
    send_end.close() # child must be the only one with it opened
    p.join(timeout)
    if p.is_alive():
        ####debug('%s timeout', args)
        p.terminate()
    else:
        return receive_end.recv()  # get value from the child
#!/usr/bin/env python
import logging
import time
from functools import partial
from multiprocessing.pool import ThreadPool

debug = logging.getLogger(__name__).debug

def run_mp(n, send_end):
    start = time.time()
    debug('%d starting', n)
    try:
        time.sleep(n)
    except Exception as e:
        debug('%d error %s', n, e)
    finally:
        debug('%d done, elapsed: %.3f', n, time.time() - start)
    send_end.send({n: n*n})

if __name__=="__main__":
    tasks = [1, 2, 4, 1, 8, 2]

    logging.basicConfig(format="%(relativeCreated)04d %(message)s", level=logging.DEBUG)
    print(ThreadPool(processes=4).map(partial(run_with_timeout, 3, run_mp), tasks))
0027 1 starting
0028 2 starting
0030 4 starting
0031 1 starting
1029 1 done, elapsed: 1.002
1032 1 done, elapsed: 1.002
1033 8 starting
1036 2 starting
2031 2 done, elapsed: 2.003
3029 (4,) timeout
3038 2 done, elapsed: 2.003
4035 (8,) timeout
[{1: 1}, {2: 4}, None, {1: 1}, None, {2: 4}]