首页 / 踩坑 / 多进程踩坑

多进程踩坑

发布于 2019-9-19 01:40:01 作者 somewheve 来自 踩坑

阿西吧 阿西吧 阿西吧


真的坑, 我在编写ctpbee的24小时 运行模块的时候踩的一些巨坑---- windows/linux


一方面是由于我编程经验不足, 一方面这确实是一个大坑.

所以我在此记录这个神奇的踩坑旅程


开始

首先我是刷刷的就写完了代码, 不要怀疑就是copy以前的代码. 然后在linux运行, ok么得问题, 代码如下:

class Hickey(object):
    """ ctpbee进程调度 """

    logger = logging.getLogger("ctpbee")

    def __init__(self):
        self.names = []

    def auth_time(self, current: datetime):
        from datetime import time
        DAY_START = time(8, 57)  # 日盘启动和停止时间
        DAY_END = time(15, 5)
        NIGHT_START = time(20, 57)  # 夜盘启动和停止时间
        NIGHT_END = time(2, 35)
        if ((current.today().weekday() == 6) or
                (current.today().weekday() == 5 and current.time() > NIGHT_END) or
                (current.today().weekday() == 0 and current.time() < DAY_START)):
            return False
        if current.time() <= DAY_END and current.time() >= DAY_START:
            return True
        if current.time() >= NIGHT_START:
            return True
        if current.time() <= NIGHT_END:
            return True
        return False

    def run_all_app(self):
        from ctpbee.context.proxy import _app_context_ctx
        for x in _app_context_ctx._simple.values():
            active = getattr(x, "active")
            if not active and x.name not in self.names:
                x.start()
                self.names.append(x.name)
            else:
                continue

    def start_all(self):
        """ 开始进程管理 """
        p = None
        while True:
            """ """
            current = datetime.now()
            status = self.auth_time(current)
            if p is None and status == True:
                p = Process(target=self.run_all_app)
                p.start()
                self.logger.info("启动程序")
            if not status and p is not None:
                self.logger.info("查杀子进程")
                import os
                import platform
                if platform.uname().system == "Windows":
                    os.popen('taskkill.exe /pid:' + str(p.pid))
                else:
                    import signal
                    os.kill(p.pid, signal.SIGKILL)
                self.logger.info("关闭成功")
                p = None
            sleep(30)




第三步 强攻
    def __repr__(self):
        return "ctpbee 7*24 manager "


上面明眼人是可以看的懂的....


第二步 尝试

我尝试将其部署到的杨的windows上面. 然后遇到了大坑 .发现进程死活都拉不起

遂尝试进行调试, 无果, 当场心急如焚, 求助大佬 yutiansut. 再说句阿西吧 ! 在此过程中发现run_all_app函数中 的_app_context_ctx中没有app变量. 发现共享变量出现了问题 ,然后yutiansut 告诉我进程共享变量有深坑. 我不信, 遂尝试将_app_context_ctx传入进去 , 哦或, 报了一大堆错, 具体不好进行粘贴.



第三步 强攻

上述直接尝试失败, 然后百度发现是因为pickle无法复制这种特殊的变量出错 . 然后搜到解决方案,尝试

from multiprocessing.managers import BaseManager

manager = BaseManager()
manager.register("LocalStack", LocalStacl) # LocalStack是_app_context_ctx的类型 

然后将_app_context_ctx传入进去 , 还是不行 ,提示弱引用对象无法支持


第四步 死心


发现自己傻逼 ,为什么不把创建变量 的代码传入到子进程中去 代码如下:


def run(func):
  app = func()
  app.start()

p = Process(target=func, args=(create_app, ))
p.start()

great !

成功运行

然后提醒下大家,. python 的多进程很多坑 ,如果多进程编程经验不足 ,先尝试动动脑子来解决 ~~~ 纪念我失智 的三个小时.....

留言

当前暂无人留言!