2014-09-01 51 views
0

我正在编写一个应用程序,它将在ubuntu 14.04上作为守护程序运行。这个守护进程的目的是运行一个for循环来检查各种数据库表中的数据,如果数据存在,它会产生一个goroutine来对各种数据进行各种操作。这样做的目的是让我更经常地执行任务,而不是让cron让我安排任务。Exec.Command中断

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

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

是的。我需要去执行一些PHP脚本。我没有足够的时间来重写所有的PHP代码,所以我不得不以某种方式来完成这项工作。

我已经设法编写守护进程,以便在SIGINT发送给守护进程时,它会进行基本正常关闭。它会让所有的goroutines完成他们的任务,这样就不会在半途停止工作,最终导致问题。

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

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

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

所以我的问题是:有没有办法允许在goroutine中启动的exec.Command()运行直到守护进程收到SIGINT时完成?如果没有,还有另外一种方法去执行go命令并允许它运行直到守护进程接收到SIGINT后完成为止。

回答

2

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

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

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

这工作完美!谢谢。 – wey23 2014-09-01 07:54:49

+0

另外你可能不需要执行shell来运行一个php脚本,你可以直接使用'exec.Command(“php”,“/var/app/send_notification.php”)。 – OneOfOne 2014-09-01 13:33:17