V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
zxCoder
V2EX  ›  Python

fastapi 收到一个 http 请求后,就创建一个新的 Thread,去执行一个机器学习模型代码,这块代码是我不懂也不可控的。我想知道有没有办法,可以控制杀死这个线程及所有相关的线程。

  •  
  •   zxCoder · 2021-10-31 22:41:11 +08:00 · 2896 次点击
    这是一个创建于 1110 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这个模型代码单独运行时,如果我按 ctlr+C 停止的话,都很难直接停下来,里头好像有用到多线程啥的,反正太深层了看不懂。

    以至于套到 fastapi 上之后,如果已经触发在跑这个模型了,我直接关掉 fastapi 程序也很难,ctlr+C 通常是关不了,只能直接 kill 。

    有没有什么好一点的方法呢,可以让这个正在跑的 Thread 不管三七二十一,就给停下来,删掉。

    10 条回复    2021-11-03 07:18:44 +08:00
    leimao
        1
    leimao  
       2021-10-31 22:53:12 +08:00 via iPhone
    Kill thread 很难,似乎很少有办法。Kill process 可以,只要知道 PID 就行了。可以尝试一下和下面 Kill distributed training 类似的思路。
    https://leimao.github.io/blog/Kill-PyTorch-Distributed-Training-Processes/
    ipwx
        2
    ipwx  
       2021-10-31 22:58:30 +08:00
    对,用 多进程,直接 os.kill
    feiandxs
        3
    feiandxs  
       2021-10-31 22:59:16 +08:00
    fastapi 跑一个 api ,作为触发没问题,但我不建议直接在 fastapi 里调用。 是我的话我宁愿接个 celery 或者更简单的做个实现,来告知有个任务,然后由别的运行服务来进行对模型的调用。

    并且对这样的模型的调用我也不觉得直接调用好,应该关进一个笼子里,笼子本身对资源占用,对进程管理做更好的管控。 其实我看你也就是想要这样的东西。

    有个想法,其实可以用 py 来调 shell ,shell 来干这个杀的事。。。
    ClericPy
        4
    ClericPy  
       2021-10-31 23:07:51 +08:00
    接 celery 就太多不可控的东西了...

    python 和多数语言一样线程是系统那边原生的, 很难杀死, 如果不嫌麻烦就丢到 Serverless 上?

    嫌麻烦的话, 如果 fastapi 启动线程也用的 run_in_executor 那个, 用的时候用多进程那个 ProcessExecutor 就可以杀了(不过没试过 cancel 掉的时候会不会杀掉, 一般 INTSIG 会一路传递过去), 一般状态切换不频繁的多进程实际没多大开销, 应该能满足你.
    niubee1
        5
    niubee1  
       2021-11-01 00:33:35 +08:00
    你只有用多进程,线程的话因为 GIL ,不适用于 CPU 密集的环境
    abersheeran
        6
    abersheeran  
       2021-11-01 09:06:53 +08:00
    你用 async def 就不会新开一个线程了,反正你跑的是机器学习代码,全是硬核运算,没必要开线程池。这个隐式转换真的是不咋地的设计。
    locoz
        7
    locoz  
       2021-11-01 09:07:50 +08:00 via Android   ❤️ 2
    简单点可以直接跑个容器,需要停的时候直接杀容器,里面再怎么样也得停…
    wwqgtxx
        8
    wwqgtxx  
       2021-11-01 09:49:53 +08:00
    如果有系统权限的话,试试 cgroups 相关的工具,比如 systemd-run 或者干脆上 docker 容器,这样能杀的比较干净
    ospider
        9
    ospider  
       2021-11-01 09:57:15 +08:00   ❤️ 1
    你这题目就错得离谱,不知道下边一群人答得什么劲……我没记错的话,FastAPI 用的是 ThreadPoolExecutor ,每次请求都开一个线程那开销得多大啊?

    看看 FastAPI 自带的 BackgroundTasks 可不可以,或者试试用 gunicorn 部署。
    leimao
        10
    leimao  
       2021-11-03 07:18:44 +08:00 via iPad
    @ospider 楼主表达问题给人的感觉就是 fastapi 是一个机器学习框架。机器学习不建议使用 Python 的多线程。这个不能怪我们这些不懂 fastapi 的人。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5389 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 07:35 · PVG 15:35 · LAX 23:35 · JFK 02:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.