杀死Python多处理P

2024-09-19 20:46:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在运行一个Python程序,它使用多处理模块生成一些工作线程。使用Pool.map这些摘要文件列表。

在某种程度上,我想停止一切,让剧本消亡。

通常,来自命令行的Ctrl+C可以完成此任务。但是,在这个例子中,我认为这只会打断其中一个工人,并且会产生一个新工人。

因此,我最终运行ps aux | grep -i python,并在有问题的进程id上使用kill -9

有没有更好的方法让中断信号把一切都停下来?


Tags: 模块文件命令行程序map列表线程grep
3条回答

不幸的是,在Python2.x中并没有一个很好的解决方案。我知道最好的解决方法是使用pool.map_async(...).get(timeout=<large number>),而不是pool.map。问题是pool.map调用threading.Condition.wait(),这由于某种原因不能被Python 2.x中的Ctrl+C中断(它在Python 3中工作)。当您使用map_async()时,它调用threading.Condition.wait(timeout=<large number>),最后会执行一个繁忙的等待循环,这个循环可以被Ctrl+C中断

你自己试试吧:

c = threading.Condition()
try:
    c.acquire()
    c.wait()  # You won't be able to interrupt this
except KeyboardInterrupt:
    print("Caught it")

c = threading.Condition()
try:
    c.acquire()
    c.wait(timeout=100)  # You CAN interrupt this
except KeyboardInterrupt:
    print("Caught it")

因此,要使您的map调用可中断,请执行以下操作:

if __name__ == "__main__":
    p = multiprocessing.Pool()
    try:
        p.map_async(func, iterable).get(timeout=10000000)
    except KeyboardInterrupt:
        print("Caught it")
        # Optionally try to gracefully shut down the worker processes here.
        p.close()
        # DON'T join the pool. You'll end up hanging.

另外请注意,正如phihag所指出的,这个问题在Python 3.4中得到了修复(可能在3.x中更早的版本)。

有几种方法。第一种方法是使用

在穿线方面

myThread.setDaemon(true)

在多处理中

myThread.daemon = True

所有标记为守护进程的线程都将与主线程一起终止。这不是正确的方法,因为它不允许线程清理

下一种方法是使用try catch监听KeyboardInterrupt,然后.join()这样的线程。

try:
    myThread = MyThread()
except KeyboardInterrupt:
    myThread.join()

如果线程处于循环中,则可以使用布尔值等条件,将其设置为false,当条件为false时,它将执行清理。

class MyThread(Threading.thread):
    def __init__(self):
        self.alive=True
    def run(self):
        while self.alive:
            #do stuff
        #cleanup goes here, outside the loop
try:
    myThread = MyThread()
except KeyboardInterrupt:
    myThread.alive = False
    myThread.join()

SIGQUIT(Ctrl+\)将杀死所有进程,即使在Python 2.x下也是如此

您还可以更新到Python3.x,在这里,这种行为(只有子级获得信号)似乎已经被修复。

相关问题 更多 >