Python服务运行多日后无法重新生成后台进程问题排查
问题分析:Python multiprocessing长期运行后无法创建子进程(SemLock FileNotFoundError)
错误日志
Jun 23 14:23:46 srv gunicorn[2717986]: Traceback (most recent call last): Jun 23 14:23:46 srv gunicorn[2717986]: File "<string>", line 1, in <module> Jun 23 14:23:46 srv gunicorn[2717986]: File "/usr/lib/python3.8/multiprocessing/spawn.py", line 116, in spawn_main Jun 23 14:23:46 srv gunicorn[2717986]: exitcode = _main(fd, parent_sentinel) Jun 23 14:23:46 srv gunicorn[2717986]: File "/usr/lib/python3.8/multiprocessing/spawn.py", line 126, in _main Jun 23 14:23:46 srv gunicorn[2717986]: self = reduction.pickle.load(from_parent) Jun 23 14:23:46 srv gunicorn[2717986]: File "/usr/lib/python3.8/multiprocessing/synchronize.py", line 110, in __setstate__ Jun 23 14:23:46 srv gunicorn[2717986]: self._semlock = _multiprocessing.SemLock._rebuild(*state) Jun 23 14:23:46 srv gunicorn[2717986]: FileNotFoundError: [Errno 2] No such file or directory
可能的原因分析
临时文件系统(/tmp)被自动清理
Linux系统通常会定期清理/tmp目录下的过期文件(比如通过systemd-tmpfiles-clean服务)。Python multiprocessing的SemLock默认在/tmp创建对应的临时文件,若父进程持有的SemLock文件被清理,新子进程启动时重建SemLock就会找不到文件,触发错误。长期运行的服务更容易遭遇此情况,因为旧的临时文件会被纳入清理范围。同步原语资源未彻底释放
关闭子进程时,若未正确清理关联的同步对象(如Semaphore、Lock),比如直接调用terminate()而非join(),或未调用同步对象的close()/release()方法,会导致父进程保留无效的SemLock引用。当创建新子进程时,这些失效的同步对象被序列化传递,子进程尝试重建时就会找不到对应的底层文件。Spawn启动模式的序列化失效问题
Spawn模式启动子进程时会重新导入主模块并反序列化父进程传递的对象。若父进程存在全局同步对象,长期运行中这些对象的底层资源可能已被释放,但父进程仍持有引用。新子进程启动时,反序列化这些失效对象,就会触发SemLock重建失败的错误。文件描述符泄漏
长期运行的服务若存在文件描述符泄漏,会耗尽系统允许的最大文件描述符数。虽然错误表现为FileNotFound,但底层可能是无法创建新的SemLock临时文件,或SemLock关联的文件描述符被意外关闭,导致后续重建时找不到文件。
内容的提问来源于stack exchange,提问作者Matthias
相关产品推荐
相关产品推荐

