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

Shiny应用关闭时如何终止所有关联的正在运行进程?

问题根因

原代码使用阻塞式的processx::run(wait=TRUE)调用,会完全卡住Shiny服务端的事件循环,导致服务端无法感知到客户端已经断开连接,自然也无法执行子进程清理逻辑,最终出现残留进程阻塞后续请求的问题。

解决方案

Linux环境下可以通过非阻塞子进程+会话结束回调的方案彻底解决该问题:

核心实现思路

  • 放弃阻塞式的processx::run()调用,改用processx::process类创建非阻塞子进程,避免阻塞Shiny会话的事件循环,让会话可以正常监听到客户端断开事件
  • 注册session$onSessionEnded回调函数,在用户关闭浏览器、会话终止时主动杀死关联的子进程及其衍生的所有子进程,避免孤儿进程残留
  • 通过invalidateLater循环监听进程状态,实现原来同步等待运行结束的业务逻辑,同时不阻塞会话事件响应

可运行修改版代码

library(shiny)
library(processx)

ui <- fluidPage(
  actionButton("runBtn", label="Run a program that consumes many resources"),
  verbatimTextOutput("status")
)

server <- function(input, output, session) {
  current_process <- NULL
  process_status <- reactiveVal("Idle")
  
  observeEvent(input$runBtn, {
    if (!is.null(current_process) && current_process$is_alive()) {
      process_status("Already running, please wait or refresh the page to terminate")
      return()
    }
    
    current_process <<- process$new(
      command = "sleep",
      args = "240",
      cleanup_tree = TRUE,
      supervise = TRUE
    )
    process_status("Process running...")
    
    session$onSessionEnded(function() {
      if (!is.null(current_process) && current_process$is_alive()) {
        current_process$kill_tree()
        # Linux专属兜底杀进程逻辑,确保多级子进程全被清理
        # system(paste0("kill -TERM -- -", current_process$get_pid()), wait = FALSE)
      }
    })
    
    observe({
      invalidateLater(1000, session)
      if (is.null(current_process) || !current_process$is_alive()) {
        process_status("Process finished")
        current_process <<- NULL
      }
    })
  })
  
  output$status <- renderPrint(process_status())
}

shinyApp(ui, server)

关键说明

  • cleanup_tree = TRUE:processx 3.2.0+版本支持的参数,主进程被终止时会自动杀死其衍生的所有子进程,避免孤儿进程残留
  • session$onSessionEnded:Shiny原生会话生命周期回调,会在用户关闭浏览器、页面刷新、会话超时的时候触发,是执行清理逻辑的最佳时机
  • 如果你运行的重型程序会启动多级子进程,可以打开Linux专属兜底杀进程逻辑的注释,直接杀死整个进程组下的所有进程,不会有任何残留

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:57:04