Python multiprocessing库apply_async函数用法困惑:我遗漏了什么?
理解multiprocessing.apply_async的问题分析
嘿,我来帮你拆解这段代码里的问题,你没搞懂的点主要在Pool对象的生命周期和异步任务的存活逻辑上,咱们一步步看:
你代码里的核心问题
1. 局部Pool对象被提前销毁
你的test_launcher函数里,pool是个局部变量——函数执行完之后,这个pool就会被Python的垃圾回收机制回收。而multiprocessing.Pool在被销毁时,会自动调用terminate()方法,直接终止所有正在运行的子进程,不管你的test函数有没有执行完。
也就是说,你的test函数刚睡了5秒(还没到15秒),pool就没了,子进程直接被干掉,自然不会打印"test"。
2. 没有处理异步任务的等待逻辑
apply_async是非阻塞的——它把任务丢给子进程后,主进程会继续往下走,不会等任务完成。但如果不主动等待或者保持Pool存活,任务根本没机会跑完。
修改后的代码示例
咱们调整一下代码,解决这两个问题:
from multiprocessing import Pool import time import threading def test(): time.sleep(15) print("test") # 注:Python3中print是函数需加括号,Python2可省略 def test_launcher(): # 将pool设为全局变量,避免函数结束后被回收 global pool pool = Pool(processes=1) result = pool.apply_async(test) # 若需等待任务完成,可在此调用result.get() # result.get() # 会阻塞直到test执行完毕 def printit(): threading.Timer(5.0, printit).start() print(time.strftime("%H:%M:%S", time.gmtime())) if __name__ == '__main__': print("Before") test_launcher() printit() # 等待子进程任务完成(可选,根据需求选择) # pool.close() # 关闭Pool,不再接受新任务 # pool.join() # 等待所有已提交任务执行完毕
关键知识点补充
apply_async的工作逻辑:它将任务提交到Pool的任务队列,空闲的子进程会从队列里取任务执行。主进程不会阻塞,但必须保证Pool在任务执行期间一直存活。- 如果不想用全局变量,也可以把
pool作为返回值从test_launcher里返回,在主进程中管理它的生命周期,避免被提前回收。 - 如果需要等待异步任务完成,除了
result.get(),还可以用pool.close()+pool.join()的组合——close()禁止提交新任务,join()等待所有已提交的任务执行完毕。
内容的提问来源于stack exchange,提问作者morpheus65535
相关产品推荐
相关产品推荐

