Python多进程共享Queue的继承问题及Manager.Queue报错求解
报错原因解析
1. RuntimeError: Queue objects should only be shared between processes through inheritance
普通multiprocessing.Queue存在设计限制:它仅支持通过进程继承的方式在父子进程间共享,不能作为参数通过Process构造方法的args传递。因为多进程在spawn启动模式(Windows默认,高版本macOS/Linux也可配置)下会对传入的参数做序列化处理,而普通Queue实例无法被序列化,直接传递就会触发该报错。
2. FileNotFoundError: [Errno 2] No such file or directory
Manager.Queue依赖Manager启动的独立服务进程实现跨进程通信,服务进程会创建本地socket/命名管道文件用于队列操作的交互。你代码中主进程在启动定时任务子进程后没有任何阻塞逻辑,会直接退出,Manager服务进程也会随之被系统回收,对应的通信管道文件被删除。等定时任务触发要操作队列时,子进程找不到对应的通信文件,就会抛出该错误。
解决方案
你可以按以下步骤修改代码修复问题:
- 修复主进程提前退出问题:主进程启动子进程后调用
join()方法阻塞等待子进程运行,避免Manager服务被提前回收。 - 修正变量名冲突问题:你在主进程中用了
schedule作为进程变量名,覆盖了导入的schedule模块,属于不规范写法,建议修改变量名避免潜在问题。 - 队列选型可任选以下两种方案:
- 方案一:继续使用
Manager.Queue,无需额外调整队列逻辑,仅修复主进程退出问题即可。 - 方案二:使用普通
multiprocessing.Queue,仅需保证队列在父进程创建后通过继承方式共享,若运行环境为Linux/macOS的fork启动模式,也可直接作为参数传递。
修正后的代码示例
from multiprocessing import Process, Manager, Queue import schedule import time def checkBirthdays(accountQueue): print('[CheckBirthdays] Initated') acc = { 'email': 'demo@test.com' } accountProcessing = [] if accountQueue.empty() else list(accountQueue.get()) accountProcessing.append(acc) accountQueue.put(accountProcessing) def createSchedule(accountQueue): schedule.every().day.at("23:51").do(checkBirthdays, accountQueue) while True: schedule.run_pending() time.sleep(60) def main(): manager = Manager() accountQueue = manager.Queue() # 修改变量名,避免覆盖schedule模块 schedule_process = Process(target=createSchedule, args=(accountQueue,)) schedule_process.start() # 阻塞主进程,等待子进程运行 schedule_process.join() if __name__ == '__main__': main()
内容的提问来源于stack exchange,提问作者TehPirate
相关产品推荐
相关产品推荐

