subprocess.run()触发Python全局线程限制致脚本崩溃求助
问题解答
这个问题在Windows平台的Python环境下确实有不少开发者遇到过,核心和subprocess.CREATE_NO_WINDOW标志的使用、Windows线程资源的累积回收机制直接相关。
问题根源
- Windows系统中,当
subprocess.run()指定CREATE_NO_WINDOW时,Python的subprocess模块会额外创建辅助线程处理控制台窗口的隐藏逻辑。这些线程虽会在子进程结束后终止,但Windows对线程相关资源(如线程ID、内核对象)的回收存在延迟,长期高频调用(比如每分钟一次,持续数月)会导致资源耗尽,最终触发崩溃。 - 你观察到的每次调用创建两个线程是正常现象:一个用于执行ping任务,另一个是
CREATE_NO_WINDOW带来的控制台辅助线程。
可行解决方案
1. 替换CREATE_NO_WINDOW为DETACHED_PROCESS
改用subprocess.DETACHED_PROCESS标志,它不会创建额外的控制台辅助线程,直接让子进程脱离父进程控制台:
import subprocess import time PING_SIZE = "1" PING_RETRYS = "1" while True: try: result = subprocess.run( ["ping", "-n", PING_RETRYS, "-l", PING_SIZE, e.ip], creationflags=subprocess.DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) ping_status = result.returncode == 0 except Exception as e: print(e) break time.sleep(60)
2. 直接调用系统API执行ping
用ctypes调用Windows原生的icmp.dll执行ping,完全绕开subprocess的线程开销:
import ctypes import time class IP_OPTION_INFORMATION(ctypes.Structure): _fields_ = [ ("Ttl", ctypes.c_ubyte), ("Tos", ctypes.c_ubyte), ("Flags", ctypes.c_ubyte), ("OptionsSize", ctypes.c_ubyte), ("OptionsData", ctypes.c_char_p) ] class ICMP_ECHO_REPLY(ctypes.Structure): _fields_ = [ ("Address", ctypes.c_ulong), ("Status", ctypes.c_ulong), ("RoundTripTime", ctypes.c_ulong), ("DataSize", ctypes.c_ushort), ("Reserved", ctypes.c_ushort), ("Data", ctypes.c_char_p), ("Options", IP_OPTION_INFORMATION) ] icmp = ctypes.WinDLL("icmp.dll") handle = icmp.IcmpCreateFile() PING_SIZE = 1 PING_RETRYS = 1 while True: try: ip_addr = ctypes.inet_addr(e.ip.encode('utf-8')) send_buf = b' ' * PING_SIZE reply_buf = ctypes.create_string_buffer(ctypes.sizeof(ICMP_ECHO_REPLY) + PING_SIZE) reply_len = ctypes.c_ulong(ctypes.sizeof(reply_buf)) status = icmp.IcmpSendEcho( handle, ip_addr, send_buf, PING_SIZE, None, reply_buf, reply_len, 1000 # 超时时间(毫秒) ) ping_status = status > 0 except Exception as e: print(e) break time.sleep(60) icmp.IcmpCloseHandle(handle)
3. 定期释放资源
如果业务允许,可以适当延长ping间隔,或者在累计一定调用次数后自动重启脚本,清空累积的系统资源。
总结
这类属于Windows平台特有的subprocess线程资源累积问题,已经有不少开发者在长期运行的定时任务场景中遇到过,上述方案都能有效缓解或解决崩溃问题。
内容的提问来源于stack exchange,提问作者Thewafflication
相关产品推荐
相关产品推荐

