You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3中sys.exit()无法终止子进程及内存占用异常求助

问题分析和解决思路

嘿,我来帮你拆解下为啥Python3里这个子进程退不掉,还有内存泄漏的问题~

为啥子进程没法终止?

核心原因是日志线程在拖后腿:
你在backUp里启动的self.logger是个普通线程(Python默认线程都是非守护线程),在Python3中,当子进程调用sys.exit()时,只会终止子进程的主线程,但子进程会一直等着所有非守护线程跑完才会真正退出。所以不是sys.exit()没用,是日志线程没结束,导致整个子进程没法退出。

至于Python2里能正常运行,大概率是之前的日志线程在Python2里有隐含的退出条件,或者线程逻辑在Python2下能自然结束,但迁移到Python3后这个差异暴露出来了。

为啥内存会被耗尽?

每次引脚触发下降沿,你都会调用Process(target=self.backUp).start()创建新进程,但之前的backup进程因为日志线程的原因根本没退出,这些“僵尸”进程会一直占着内存,次数多了内存自然就被耗干了。


怎么解决?

给你三个实用方案,按需选:

1. 把日志线程改成守护线程

这是最简单的办法,只要在启动日志线程前,把它的daemon属性设为True。守护线程的特点是:只要主进程/主线程退出,它会被强制终止,不会拖后腿。

def backUp(self):
    """ 用于创建备份反馈日志。@return: None. """
    if product is not None:
        self.logger.__init__()
        # 设为守护线程,主线程退出时它会跟着结束
        self.logger.daemon = True
        self.logger.start()
        # do some stuff
        sys.exit()

2. 手动停止日志线程再退出

如果你的日志必须写完所有内容才能退出,不能用守护线程,那就在sys.exit()前,主动让日志线程停止,并等待它结束。比如给你的日志线程类加个停止方法:

# 假设你的logger是继承threading.Thread的类
class LoggerThread(threading.Thread):
    def __init__(self):
        super().__init__()
        # 加个标记控制线程循环
        self._should_run = True

    def run(self):
        # 原来的日志逻辑改成循环,用_should_run控制
        while self._should_run:
            # 执行日志写入操作
            pass

    def stop(self):
        # 标记线程停止
        self._should_run = False

然后在backUp里调用:

def backUp(self):
    """ 用于创建备份反馈日志。@return: None. """
    if product is not None:
        self.logger.__init__()
        self.logger.start()
        # do some stuff
        # 先停止日志线程,等它把剩余日志写完
        self.logger.stop()
        self.logger.join()  # 等待线程结束
        sys.exit()

3. 避免重复创建进程

加个标志位,每次触发引脚事件时,先检查有没有正在运行的backup进程,如果有就不创建新的,这样就不会堆进程了:

# 先在类的__init__里加个进程实例变量
def __init__(self):
    # 其他初始化代码...
    self.backup_process = None

def pin_event_down(self):
    """ 用于创建产品引脚事件。@return: None. """
    # do some stuff
    # 检查进程是否存在且存活,只有不存在/已结束才创建新的
    if not (self.backup_process and self.backup_process.is_alive()):
        self.backup_process = Process(target=self.backUp)
        self.backup_process.start()
    # do some stuff

这样三个方案结合起来,应该就能解决你的问题啦~

内容的提问来源于stack exchange,提问作者Jasper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:08:14