Windows下实现独立Python进程:父进程终止后仍持续运行
在Windows上创建完全脱离主进程的独立Python子进程
针对你在Windows环境下的需求,以下是两种经过验证的方案,确保子进程在主进程终止后仍能持续运行并重试邮件发送:
方案一:直接用pythonw.exe启动子进程并配置关键参数
Windows系统中,python.exe会绑定到主进程的控制台会话,而pythonw.exe是无窗口版本,能更好地脱离主进程控制。结合正确的进程创建参数,可实现完全独立的子进程:
修改你的main process.py代码如下:
import subprocess import sys # 替换为实际的test_email_send.py路径 script_path = "path/to/test_email_send.py" # 使用pythonw.exe替代python.exe,避免控制台关联 python_exe = sys.executable.replace("python.exe", "pythonw.exe") # 构建启动命令 cmd = [python_exe, script_path, "test1", "test2"] # 启动独立子进程 p1 = subprocess.Popen( cmd, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.DETACHED_PROCESS, close_fds=True, # 关闭所有继承自主进程的文件句柄,彻底切断关联 shell=False )
参数说明:
pythonw.exe:无窗口运行Python,不依赖主进程的控制台,主进程终止时不会被连带关闭close_fds=True:强制子进程不继承主进程的任何文件句柄,避免主进程关闭句柄时影响子进程CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS:创建独立进程组并脱离主进程控制台,进一步隔离进程关系
方案二:通过批处理脚本中转(更可靠)
如果方案一仍有问题,可通过批处理脚本作为中间层,利用Windows的start命令彻底分离进程:
- 创建
run_email_task.bat脚本:
@echo off # /B参数表示后台启动,不打开新控制台窗口 start /B pythonw.exe "path/to/test_email_send.py" %* # 批处理执行完立即退出,不残留进程 exit
- 主进程中调用该批处理:
import subprocess cmd = ["cmd.exe", "/c", "path/to/run_email_task.bat", "test1", "test2"] p1 = subprocess.Popen( cmd, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.DETACHED_PROCESS, close_fds=True, shell=False )
注意事项
- 不要使用
multiprocessing的Daemon进程:Daemon进程会随主进程的退出被强制终止,不符合你的需求 - 子进程需自行实现重试逻辑:在
test_email_send.py中加入循环重试逻辑,例如:
import time import smtplib from email.mime.text import MIMEText def send_email(): # 你的邮件发送逻辑,成功返回True,失败返回False try: msg = MIMEText("检查结果内容") msg["Subject"] = "检查结果通知" msg["From"] = "your_email@example.com" msg["To"] = "recipient@example.com" with smtplib.SMTP_SSL("smtp.example.com", 465) as server: server.login("your_email@example.com", "your_password") server.send_message(msg) return True except Exception as e: print(f"发送失败: {str(e)}") return False # 重试30分钟,每5分钟尝试一次 max_retry_time = 30 * 60 retry_interval = 5 * 60 start_time = time.time() while time.time() - start_time < max_retry_time: if send_email(): break time.sleep(retry_interval)
测试验证
运行主进程后,手动结束主进程,打开任务管理器查看是否存在pythonw.exe进程,等待一段时间后检查邮件是否发送成功。
内容的提问来源于stack exchange,提问作者Luke M
相关产品推荐
相关产品推荐

