Python和多处理......如何在主进程中调用函数?

时间:2011-03-06 04:52:47

标签: python multiprocessing

我想在python中实现异步回调样式函数...这就是我想出来的但我不确定如何实际返回主进程并调用函数。

funcs = {} 

def runCallback(uniqueId):
    '''
    I want this to be run in the main process.
    '''
    funcs[uniqueId]()


def someFunc(delay, uniqueId):
    '''
    This function runs in a seperate process and just sleeps.  
    '''
    time.sleep(delay)

    ### HERE I WANT TO CALL runCallback IN THE MAIN PROCESS ###

    # This does not work... It calls runCallback in the separate process:
    runCallback(uniqueId)


def setupCallback(func, delay):
    uniqueId = id(func)
    funcs[uniqueId] = func
    proc = multiprocessing.Process(target=func, args=(delay, uniqueId))
    proc.start()
    return unqiueId

以下是我希望它的工作方式:

def aFunc():
    return None

setupCallback(aFunc, 10)
### some code that gets run before aFunc is called ###
### aFunc runs 10s later ###

这里有一个问题,因为我希望这有点复杂。基本上当主进程中的代码完成运行时...我想检查funcs dict然后运行任何尚未运行的回调。这意味着runCallback还需要从funcs dict中删除条目... funcs dict不与单独的进程共享,所以我认为runCallback需要在主进程中调用???

2 个答案:

答案 0 :(得分:4)

目前还不清楚为什么在这里使用multiprocessing模块。

要在同一过程中调用延迟函数,您可以使用threading.Timer

threading.Timer(10, aFunc).start()
如果您想稍后取消回调,

Timer.cancel()方法:

t = threading.Timer(10, runCallback, args=[uniqueId, funcs])
t.start()
timers.append((t, uniqueId))
# do other stuff
# ...
# run callbacks right now
for t, uniqueId in timers:
    t.cancel() # after this the `runCallback()` won't be called by Timer()
               # if it's not been called already
    runCallback(uniqueId, funcs)

修改runCallback()以删除要调用的函数:

def runCallback(uniqueId, funcs):
    f = funcs.pop(uniqueId, None) # GIL protects this code with some caveats
    if f is not None:
       f()

答案 1 :(得分:3)

要完成你想要做的事情,你需要在父进程中设置一个信号处理程序来运行回调(或者只是删除子进程的回调函数,如果它没有需要访问任何父进程的内存),并让子进程发送signal,但如果你的逻辑变得更复杂,你可能需要使用另一种类型的进程间通信(IPC)例如pipessockets

另一种可能性是使用threads而不是进程,然后您可以从第二个线程运行回调。您需要添加lock来同步对funcs字典的访问权限。