python多处理池信号

时间:2014-08-12 09:14:08

标签: python signals multiprocessing pool

我遇到了一个小问题我是python中的多处理模块的初学者,我必须创建一个可以随时被SIGINT停止的池。

from multiprocessing import Pool, current_process
import signal
import time
import os

class Processor(object):
    def __init__(self, stack):
        self.stack = stack
        self.pool = Pool(processes=4, maxtasksperchild=1, initializer=self._init)

    def _init(self):
        cp = current_process()
        cp.daemon = False

    def launch(self):
        self.result = self.pool.map(func, self.stack)
        self.pool.close()
        self.pool.join()

def func(j):
    a, b = j
    time.sleep(1)
    return a * b

def breaker(*args):
    p.pool.terminate()
    p.pool.join()

def main():
    a = 4, 9
    b = 5, 7
    lst = [a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b, a, b]
    global p
    p = Processor(lst)
    signal.signal(signal.SIGINT, breaker)
    p.launch()
    ret = p.result
    for i in ret:
        print i

if __name__ == '__main__':
    print os.getpid()
    main()

没有任何信号代码被完美地执行但是当我向这个过程发送信号时,这不再工作,并且永远不会调用断路器功能。 如果有人知道为什么。

1 个答案:

答案 0 :(得分:0)

断路器功能会被调用,但如果你添加,它不会告诉你的主要退出:

sys.exit(os.EX_OK)

或断路器末端的任何其他出口然后它将实际退出。

你也可能想要移动它:

signal.signal(signal.SIGINT, breaker)
池定义之前的

应该在子进程中停止未处理的键盘中断

要获得部分结果,您可能需要执行以下操作...

您的发布必须成为:

# start the workers
for el in self.stack:
    self.result[el] = self.pool.apply_async(func, (el, ), callback=your_callback)

#wait for results
for work in self.result.items(): # or iteritems if you're on pre python3
    work[1].get()

self.pool.close()
self.pool.join()

这将作为异步调用逐个执行结果,并且您的回调将有机会将它们保存到某个地方以供日后使用。

地图不会给你,因为它只会在通话结束时返回一次,因此你无法获得部分结果

然后你需要在某处将your_callback写入全局结果列表:

def your_callback(result):
    global_list.append(result)

订购可能到处都是......

现在您的结果将在global_list中逐个显示,您可以在main()或破坏者()中输出