脚本结束/中断后上传文件至S3报错:解释器关闭后无法调度新Futures
解决脚本中断时S3上传的RuntimeError问题
问题背景
需求:确保脚本无论正常结束还是被中断(比如按下CTRL+C),都能将指定文件上传至S3。
已实现的代码:
import atexit import signal atexit.register(exit_handler) signal.signal(signal.SIGINT, exit_handler) signal.signal(signal.SIGTERM, exit_handler) def exit_handler(): s3_client = boto3.client('s3') s3_client.upload_file(file,bucket, file)
触发CTRL+C中断时,出现如下报错:
File "/python3.10/site-packages/s3transfer/futures.py", line 474, in submit future = ExecutorFuture(self._executor.submit(task)) File "/python3.10/concurrent/futures/thread.py", line 169, in submit raise RuntimeError('cannot schedule new futures after ' RuntimeError: cannot schedule new futures after interpreter shutdown
问题原因
这个错误的核心是:当通过CTRL+C触发SIGINT信号时,信号处理函数和atexit注册的回调会在Python解释器开始关闭流程后执行。而boto3的upload_file默认用多线程(依赖concurrent.futures)处理上传任务,此时解释器已进入shutdown状态,无法再创建新线程/ futures,因此抛出RuntimeError。
解决方案
方案1:提前初始化S3客户端并禁用多线程
把S3客户端的初始化放在脚本启动阶段,而非退出回调中,同时配置客户端禁用多线程,避免在解释器关闭时创建新线程:
import atexit import signal import boto3 from botocore.config import Config # 提前初始化S3客户端,设置单线程连接池 s3_config = Config(max_pool_connections=1) s3_client = boto3.client('s3', config=s3_config) # 替换为你的实际文件路径和桶名 local_file_path = "your_file.txt" s3_bucket_name = "your-bucket-name" s3_object_key = "your_file.txt" def exit_handler(signum=None, frame=None): try: s3_client.upload_file(local_file_path, s3_bucket_name, s3_object_key) print("文件已成功上传至S3") except Exception as e: print(f"上传失败: {str(e)}") # 信号触发的中断,处理完成后主动退出 if signum is not None: exit(0) # 注册退出回调和信号处理 atexit.register(exit_handler) signal.signal(signal.SIGINT, exit_handler) signal.signal(signal.SIGTERM, exit_handler) # 这里放你的主程序逻辑 # ...
方案2:使用单线程上传方式
如果不想修改客户端配置,也可以改用upload_fileobj方法,手动以单线程方式读取文件并上传:
def exit_handler(signum=None, frame=None): try: with open(local_file_path, 'rb') as f: s3_client.upload_fileobj(f, s3_bucket_name, s3_object_key) print("文件已成功上传至S3") except Exception as e: print(f"上传失败: {str(e)}") if signum is not None: exit(0)
额外注意点
- 信号处理函数需要接收
signum和frame两个参数(信号触发时会自动传入),之前的无参写法可能引发潜在错误 - 建议在上传逻辑中增加异常捕获,避免上传失败时无提示信息
内容的提问来源于stack exchange,提问作者00__00__00
相关产品推荐
相关产品推荐

