我有两个程序
我尝试使用cmd.Run()
启动(2)中的守护程序进程,但这使cmd.Run()
进入(1)永远运行,可能是因为守护程序子进程延迟。
cmd := exec.Command("daemonbinary")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
// do other stuff and eventually exit the program would not work
然后我想我会使用cmd.Start()
代替,但问题是我必须等待守护程序进程实际启动才能继续。
如何实现?
总结一下,我想要达到的目标是:
修改
我尝试在一个单独的进程组中启动它:
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pgid: 0,
}
这似乎不起作用。
编辑2:
我只删除了我附加os.Stdout
和os.Stderr
的两行,现在上面的内容似乎正常。
在程序运行时,如果有stdout
和stderr
会很好吗?
答案 0 :(得分:2)
您所描述的情况听起来像过程控制系统/协调器(如docker-compose
或supervisord
),它允许您在单独的进程中运行服务并检查其状态。
如果您坚持留在Go中,我建议您定期从守护程序StdoutPipe
读取新内容,直到它出现并采取行动。但我发现这个解决方案非常糟糕。
package main
import (
"fmt"
"log"
"os/exec"
"time"
)
func main() {
cmd := exec.Command("bash", "-c", "sleep 2 && echo started && sleep 5")
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
buffer := make([]byte, 7)
for {
stdout.Read(buffer)
if string(buffer) == "started" {
break
}
time.Sleep(500 * time.Millisecond)
}
fmt.Println("Daemon started")
yourRPCStuff()
if err = cmd.Process.Kill(); err != nil {
log.Fatal("Failed to kill daemon: ", err)
}
}