最近的项目是完成用多进程进行tcp接收,以及通过消息内容进行keras模型预测。
最开始的版本:
主进程:循环接收 客户端信息
子进程:每一个新链接,创建一个子进程。
子进程对信息进行提取,提取后利用keras进行分析预测。
修改的版本1:
主进程:循环接收 客户端信息
子进程:每一个新链接,创建一个子进程。
子进程对信息进行提取,提取信息中的id号
子子进程: 每一个id号 创建一个子子进程。
子子进程进行keras分析预测。
# 推翻的原因
1. 进程太多。
2. 当链接关闭时,需关闭该链接 相关id号创建出来的子子进程。而且必须要清空对应进程的queue队列。
遇到的问题: 字典 a = {id:子子进程}
字典 b = {id:queue}。
关于这样的几个字典,在主进程创建,在子进程修改。但是主进程一直都是创建是的样子,是一个空字典。
并且,用Manager全局变量也不让存储 进程对象,队列对象。
并且,进程间不允许传递 进程对象
我的解决方案1:
主进程可以控制子进程,但不能直接控制子子进程。
所以 当关闭子进程时 使用psutil模块,查询子进程下所有子子进程,统统kill掉。但是没有清空queue,直接关了。
代码未通过 评审。
我的解决方案2(未实现):
子进程创建子子进程时,会有一个字典,存储子子进程的信息。
所以当 主进程关闭子进程时 ,先让 子进程关闭子子进程。
但是由于 主进程 和 子进程 同时运行。就会发生 子进程先被关闭,而子子进程还开着呢。
最后 子子进程 变成了僵尸进程。
主要是子进程 不能加 守护。因为 子进程 daemon = True的话,就不允许创建子子进程了。
修改的版本 2:
主进程:循环接收 客户端信息
子进程:
创建子 进程池。
对客户端消息进行解析。1类型 直接加载 keras 模型
2类型 消息投入进程池,进行预测。
子进程池:
解析消息内容,进行预测。
遇到的问题:
1.(已解决) 最开始是在主进程 里创建了 子进程 和进程池。 子进程无法给 进程池添加任务。
解决办法就是 进程池在 子进程里面创建。
2. (已解决)进程池不运行,不报错。
我的原因是,最开始,我的进程池 任务 是 类 的一个方法。self对象中含有 epoll,这个东西不能往进程池任务里面传。
解决办法就是 把进程池任务 单独创建了一个 类。
3. (未解决)在 给进程池投任务的时候,需要把 加载的keras模型 传递过去。
原因是,进程池任务 不能传入 模型对象。报错显示似乎含义是: 序列化对象不能传递。
现在 想看看 若何利用 多进程 进程keras模型分析的代码,需要推荐一下。