脚本主逻辑早就跑完,命令行就是不回到提示符,按 Ctrl+C 才退出,日志显示后台还有个线程在轮询接口。日志里能对上时间点,这种反而好排。
threading 默认创建非守护线程,解释器要等所有非守护线程结束才退出,那个线程在死循环里 sleep,主线程结束后它还在跑,进程自然退不掉。这一点先确认清楚,后面就不用反复试。
stop = threading.Event() t = threading.Thread(target=poll, args=(stop,), daemon=True) t.start() stop.set(); t.join(timeout=2)
「非守护线程退出」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。
处理上按这个顺序:后台轮询线程在创建时就把 daemon 设成真,别用默认值;用一个 Event 做退出信号,循环里每隔一轮检查一次状态;退出前 join 一小段时间,等它把手上这一步做完再退出。
结果对不对很好判断,主逻辑结束后进程在两百毫秒内退出,不再需要手动中断进程。
