结束等待mp.pool.map返回值的线程(并清理内存)

0 投票
1 回答
900 浏览
提问于 2025-04-18 10:02

我遇到了一个很尴尬的并行问题,打算用多进程库来解决。我想加个功能,就是有个图形界面(GUI)和一个取消按钮。我使用了pool.map来启动我的进程,并用pool.terminate()来关闭所有的工作进程。不过,我觉得pool.map是阻塞的,也就是说它会一直等着结果返回。同时,我还用线程来确保图形界面(Tkinter)不会卡住。

这里有一些代码,帮你理解我在说什么。

import multiprocessing
import threading
import Tkinter

def expensiveFunction()
    #do some stuff


if __name__=='main':
    master=Tkinter.Tk()
    master.title("My Title")
    master.geometry("some dimension")
    master.resizable(0,0)

    def analysisFunction():
        global pool
        #do some preprocessing stuff
        Input=[,,,] #some iterable here
        pool=multiprocessing.Pool()
        Results=pool.map(expensiveFunction,Input)

    def threadedFunction():
        myThread=threading.Thread(None,analysisFunction,None)

    def cancel():
        global pool
        pool.terminate()

    runButton=Tkinter.Button(master,text = "Run Analysis",command = threadedFunction)
    runButton.pack(fill = x)
    cancelButton=Tkinter.Button(master,text = "Cancel Analysis", command = cancel)
    cancelButton.pack(fill = x)

简单来说,当你启动这个脚本时,它会打开一个图形界面。如果你按下运行按钮,它就会开始运行;如果按下取消按钮,我能看到进程被杀掉了,但我觉得我的线程还是在等pool.map返回结果。问题是,如果我先运行再取消,主进程的内存就会不断增加,因为线程就像卡在那儿一样。

有没有什么办法可以杀掉这个线程或者释放内存呢?我需要这个线程,这样我才能在分析进行时访问我的图形界面,以便取消操作。

谢谢大家!

补充一下:总结一下我的问题,每次我按下运行按钮时,都会启动一个线程来做一些预处理的工作,这些东西都保存在内存里。然后它会启动池进程,我可以用pool.terminate()来突然取消这些进程,但当我这么做时,线程并没有关闭,所有的内存都被占用,导致我的RAM被耗尽。

1 个回答

1

使用 pool.map_asynchttps://docs.python.org/2/library/multiprocessing.html#multiprocessing.pool.multiprocessing.Pool.map_async

你可以提供一个回调函数,这样在任务完成后,你就可以在你的Tk GUI中执行一些操作。

大概会是这样的样子:

def analysisFunction():
    global pool
    #do some preprocessing stuff
    Input=[,,,] #some iterable here
    pool=multiprocessing.Pool()
    pool.map_async(expensiveFunction,Input, callback=success)

def threadedFunction(success_callback):
    myThread=threading.Thread(target=analysisFunction)

def success(results):
    # Do stuff with the results
    pass

撰写回答