【问题标题】:Exec.Command Interrupt执行命令中断
【发布时间】:2014-09-01 07:08:39
【问题描述】:

我正在编写一个将在 ubuntu 14.04 上作为守护进程运行的应用程序。该守护进程的目的是运行一个 for 循环,该循环将检查各种数据库表中的数据,如果存在数据,它将生成一个 goroutine 对各种数据执行各种操作。这样做是为了让我可以比 cron 让我更频繁地执行任务。

一个例子是,如果守护进程在数据库表“通知”中发现了一个新行,它将生成一个新的 goroutine,该 goroutine 将一直运行直到它完成,在这种情况下,这意味着运行以下命令:

err := exec.Command("sh","-c","php /var/app/send_notification.php").Run()

是的。我需要从 go 执行一些 php 脚本。我还没有时间重写 go 中的所有 php 代码,所以我必须以某种方式完成这项工作。

我已经设法编写了守护程序,因此如果向它发送 SIGINT,它将执行大部分正常关闭。它将让所有的 goroutine 完成它们的任务,这样就不会中途停止任何工作,这可能最终导致问题。

现在的问题是,只要将 SIGINT 发送到此守护程序,由 exec.Command() 启动的所有进程都会立即中止。

http://rcrowley.org/articles/golang-graceful-stop.html

上面的链接是我用作这个守护进程的模板。

所以我的问题是:有什么方法可以让在 goroutine 中启动的 exec.Command() 运行直到守护进程收到 SIGINT 时完成?如果没有,是否有另一种方法可以从 go 执行命令并在守护进程收到 SIGINT 后允许它运行直到完成?

【问题讨论】:

    标签: go


    【解决方案1】:

    新创建的进程将与您的守护进程位于同一进程组。 这意味着默认情况下,发送到您的守护进程的信号将被广播到您创建的进程。

    您可以使用Cmd 类型的SysProcAttr 属性强制您新创建的进程在命令之前位于他自己的进程组中。

    cmd := exec.Command("sh","-c","php /var/app/send_notification.php")
    cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid:true}
    error := cmd.Run()
    

    【讨论】:

    • 另外你可能不需要执行shell来运行一个php脚本,你可以直接使用exec.Command("php", "/var/app/send_notification.php")
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 2011-12-22
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    相关资源
    最近更新 更多