如何让Python文件处理函数后台运行?Flask接口调用仍阻塞页面
问题根源:线程启动方式错误导致主线程阻塞
我一眼就看出问题出在哪了——你启动后台线程的方式完全错了!现在的代码里,Thread(target=pr.recognize(conv_path))这一行是直接调用了pr.recognize(conv_path)函数,而不是把这个函数作为目标任务传给线程。这就意味着,耗时的识别操作会先在主线程里执行完毕,之后才会启动一个空线程,自然Chrome标签页会一直等待API处理完成。
修正步骤
1. 正确传递线程目标函数
把target设置为函数对象本身,用args参数传递函数需要的参数(注意args必须是元组,单个参数也要加逗号):
Thread(target=pr.recognize, args=(conv_path,), daemon=True).start()
2. 处理Flask上下文(可选但重要)
如果你的recognize函数里用到了Flask上下文相关内容(比如current_app、数据库连接等),直接在后台线程运行会报错,需要手动推送上下文:
def run_recognition(app, conv_path): with app.app_context(): pr = r.Recogniser() pr.recognize(conv_path) # 在路由中调用 Thread(target=run_recognition, args=(app, conv_path), daemon=True).start()
3. 修正后的完整路由代码
@app.route('/', methods=['GET', 'POST']) def hello_world(): if request.method == 'GET': return render_template('upload.html') else: file = request.files['file'] # 用os.path.join替代硬编码路径,更跨平台友好 temp_audio_path = os.path.join(os.getcwd(), 'tempFilesAudio') temp_transcription_path = os.path.join(os.getcwd(), 'tempFilesTransciption') if not os.path.exists(temp_audio_path): os.mkdir(temp_audio_path) if not os.path.exists(temp_transcription_path): os.mkdir(temp_transcription_path) secure_name = secure_filename(file.filename) file_path = os.path.join(temp_audio_path, secure_name) file.save(file_path) conv_path = convert(file_path) print('converted:{}'.format(conv_path)) # 正确启动后台线程 Thread(target=pr.recognize, args=(conv_path,), daemon=True).start() return redirect('/')
关于multiprocessing的补充说明
如果你尝试多进程也没生效,大概率是犯了同样的错误——直接调用函数而非传递函数对象。另外用多进程要注意:
- 进程间内存隔离,不要依赖Flask全局变量,所有需要的参数都要显式传递
- 启动方式和线程类似:
Process(target=pr.recognize, args=(conv_path,)).start()
这样修改后,耗时的识别操作会在后台线程/进程中运行,主线程会立即返回重定向响应,Chrome标签页就不会再等待了。
内容的提问来源于stack exchange,提问作者Kush Singh
相关产品推荐
相关产品推荐

