Go到目前还没有解决成为守护进程(Daemonize)的问题吧?各位是怎么解决的?

这是StackOverFlow上写的,

http://stackoverflow.com/questions/10027477/golang-fork-process/10070021#10070021

还有官网的

http://code.google.com/p/go/issues/detail?id=227

我自己试图抄了一段代码,可以工作,但问题在于我在子进程里面调用了一下time.Sleep后,子进程就不动了。用strace看到子进程卡在epoll调用上。

请问大家是怎么解决这个问题的?就用很土的nohup ./go-exec &这种shell来实现吗?

package main

import (
  "log"
  "os"
  "runtime"
  "errors"
  "syscall"
)


func daemon(chdir bool, closeStd bool) (err error){
  var ret, ret2 uintptr
  var er syscall.Errno

  darwin := runtime.GOOS == "darwin"

  // already a daemon
  if syscall.Getppid() == 1 {
    return
  }

  // fork off the parent process
  ret, ret2, er = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
  if er != 0 {
    err = errors.New("fork fail")
    return
  }

  // failure
  if ret2 < 0 {
    err = errors.New("fork fail")
    os.Exit(-1)
  }
  // handle exception for darwin
  if darwin && ret2 == 1 {
    ret = 0
  }

  // if we got a good PID, then we call exit the parent process.
  if ret > 0 {
    os.Exit(0)
  }

  /* Change the file mode mask */
  _ = syscall.Umask(0)

  // create a new SID for the child process
  s_ret, s_errno := syscall.Setsid()
  if s_errno != nil {
    log.Printf("Error: syscall.Setsid errno: %d", s_errno)
  }
  if s_ret < 0 {
    err = errors.New("setsid fail")
    return
  }

  if chdir {
    os.Chdir("/")
  }

  if closeStd {
    f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
    if e == nil {
      fd := f.Fd()
      syscall.Dup2(int(fd), int(os.Stdin.Fd()))
      syscall.Dup2(int(fd), int(os.Stdout.Fd()))
      syscall.Dup2(int(fd), int(os.Stderr.Fd()))
    }
  }

  return
}
阅读 18.5k
评论
    4 个回答
    • 1.6k
      相似问题
      推荐文章