dtja73027 2019-03-10 03:39
浏览 382
已采纳

调用cmd.Process.Kill()后,进程不会死

I've a program that tracks file change and should restart a specified process on file change.

I use cmd.Process.Kill() to kill previous process but it keeps alive after Kill() called.

Some piece of code related to process start from project:

// ShellPlugin allows to run shell commands in task runner 
type ShellPlugin struct {
    scope  *scope.Scope
    params Params
    log    logging.Logger
    done chan bool
}

// Call calls a plugin
func (p *ShellPlugin) Call(tx *job.RunContext, r plugins.JobRunner) (err error) {
    defer close(p.done)

    // process: /bin/sh -c ping google.com
    cmd, err := p.params.createProcess(p.scope)
    if err != nil {
        return fmt.Errorf("failed to create process to execute command '%s': %s", p.params.Command, err)
    }

    p.log.Debug("command: '%s'", p.params.Command)
    p.log.Debug(`starting process "%s"...`, strings.Join(cmd.Args, " "))

    if err = cmd.Start(); err != nil {
        return fmt.Errorf(`failed to execute command "%s": %s`, strings.Join(cmd.Args, " "), err)
    }

    go func() {
        select {
        case <- p.done:
            p.log.Debug("received stop signal")
            if err := cmd.Process.Kill(); err != nil {
                p.log.Warn("kill: %s", err.Error())
            }
            p.log.Debug("Killed")
        }
    }()

    if err := cmd.Wait(); err != nil {
        return formatExitError(err)
    }

    p.log.Debug("done")
    return nil
}

// Cancel called when task should be canceled
func (p *ShellPlugin) Cancel(ctx *job.RunContext) error {
    p.done <- true
    return nil
}

Call() starts job and Cancel() cancel it. Both called in separate goroutine.

Full source code is here

  • 写回答

1条回答 默认 最新

  • dongyan1548 2019-03-10 04:19
    关注

    The issue was that the main process sh was killed but child process sleep was still alive.

    The solution was to assign process group to the main process and kill a whole process group.

    // assign process group
    cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
    
    // Kill pg
    syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
    

    Solution was found here

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分