执行命令中断

huangapple go评论80阅读模式
英文:

Exec.Command Interrupt

问题

我正在编写一个应用程序,它将作为一个守护进程在Ubuntu 14.04上运行。这个守护进程的目的是运行一个for循环,检查各种数据库表中是否有数据,如果有数据,则会生成一个goroutine来对各种数据执行各种操作。这样做是为了让我可以更频繁地执行任务,而不仅仅是cron允许我调度任务的频率。

一个例子是,如果守护进程在数据库表"notifications"中发现了一行新数据,它将生成一个新的goroutine,直到完成为止,这意味着运行以下命令:

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

是的,我需要从Go中执行一些PHP脚本。目前我没有时间将所有的PHP代码重写为Go,所以我必须想办法让它工作。

我已经成功编写了守护进程,如果收到SIGINT信号,它将进行一个基本上优雅的关闭。它将让所有的goroutine完成它们的任务,以确保没有工作被中途停止,这可能会导致问题。

问题是,一旦将SIGINT信号发送给这个守护进程,由exec.Command()启动的任何进程都会立即中止。

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

所以我的问题是:当守护进程接收到SIGINT时,有没有办法让在goroutine中启动的exec.Command()运行直到完成?如果没有,是否有其他方法可以在守护进程接收到SIGINT后执行命令并允许其运行直到完成?

英文:

I'm writing an application that will run as a daemon on ubuntu 14.04. The purpose of this daemon is to run a for loop that will check for data in various database tables and if data is present it will spawn a goroutine to take various actions on various data. This is done to allow me doing tasks more often than cron allows me to schedule tasks.

An example would be if the daemon found a new row in the database table "notifications" it would spawn a new goroutine that would run until it's done, which in this case would mean running the command below:

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

Yes. I've the need to execute some php scripts from go. I don't have the time allotted to rewrite all the php code in go just yet so I'll have to make this work somehow.

I've managed to write the daemon so it will do a mostly graceful shutdown if SIGINT is sent to it. It will let all goroutines complete their tasks so that no work is stopped halfway through which may end up causing problems.

The problem is now that as soon as SIGINT is sent to this daemon, any and all processes started by the exec.Command() is aborted right away.

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

The link above is what I've used as a template for this daemon.

So my question is: Is there any way to allow an exec.Command() started in a goroutine to run until completion when the daemon receives SIGINT? If not, is there another way to go about executing a command from go and allowing it to run until completion after SIGINT is received by the daemon?

答案1

得分: 2

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

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

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

The newly created process will be on the same process group than your daemon.
This means that by default, signal sent to your daemon will be broadcast to your created processes.

You can force your newly created process to be in his own process group just before the command using the SysProcAttr attribute of the Cmd type.

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

huangapple
  • 本文由 发表于 2014年9月1日 15:08:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/25600504.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定