You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Streamlit中使用ThreadPoolExecutor调用ingestion函数遇ScriptRunContext缺失错误

问题分析与解决方案

错误原因

  1. add_script_run_ctx调用对象错误:executor.map()返回的是生成器对象,而add_script_run_ctx()需要接收线程对象或关联线程的Future对象,直接作用在生成器上会触发'generator' object has no attribute 'streamlit_script_run_ctx'错误。
  2. 子线程缺少Streamlit运行上下文:线程池中的子线程未绑定ScriptRunContext,若ingestion函数调用了Streamlit API(比如更新组件、输出内容),就会出现Thread 'ThreadPoolExecutor-8_0': missing ScriptRunContext错误——这类操作必须在有Streamlit运行上下文的环境中执行。

正确实现方式

方式一:通过submit逐个绑定上下文

使用executor.submit创建任务,给每个返回的Future对象添加上下文,确保子线程能获取Streamlit运行环境:

from streamlit.runtime.scriptrunner import add_script_run_ctx
import concurrent.futures

with concurrent.futures.ThreadPoolExecutor() as executor:
    futures = []
    # 遍历参数元组列表,逐个提交任务
    for args_tuple in final:
        future = executor.submit(ingestion, *args_tuple)
        # 给当前任务的线程绑定Streamlit运行上下文
        add_script_run_ctx(future)
        futures.append(future)
    
    # 等待所有任务执行完成(可选,根据业务需求决定是否阻塞)
    concurrent.futures.wait(futures)

方式二:包装函数传递上下文

先获取主线程的ScriptRunContext,在包装函数中为子线程设置该上下文后再执行原逻辑:

from streamlit.runtime.scriptrunner import get_script_run_ctx, set_script_run_ctx
import concurrent.futures

# 获取当前Streamlit主线程的运行上下文
main_ctx = get_script_run_ctx()

def wrapped_ingestion(*args):
    # 在子线程中设置主线程的上下文
    set_script_run_ctx(main_ctx)
    return ingestion(*args)

with concurrent.futures.ThreadPoolExecutor() as executor:
    executor.map(wrapped_ingestion, final)

注意事项

  • 确保ingestion函数中的Streamlit操作是线程安全的,避免多线程同时修改同一组件状态引发异常。
  • 如果ingestion函数不需要调用Streamlit API,无需添加上下文处理,直接使用原脚本即可。

内容的提问来源于stack exchange,提问作者Sanika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:17:22