2014-09-18 36 views
0

最後日子裏,我感到有點與派生進程奮力殺從分叉一個(孩子)的父母Golang不能殺子從父進程

我不知道爲什麼,但它似乎不殺父母在所有。首先,我堅持它的開放連接,保持進程運行,因爲優雅的關機過程,但它不是那個問題。

如果我從終端發送SIGTERM到它的父母工作完美,但是當孩子發送SIGTERM它不會停止,強制退出是沒有選擇的正常關機的原因。

編輯*進程仍在進程列表中。也許這是父母跟蹤其子女?

一些代碼,不會叉,也許我做了什麼錯在這裏

func (s *Server) Upgrade() error { 
    tl := s.listener.(*listener) 

    addr := s.listener.Addr() 
    name := fmt.Sprintf("%s:%s->", addr.Network(), addr.String()) 
    os.Setenv("PROX_NAME", name) 

    fl, err := tl.File() 
    if err != nil { 
     return fmt.Errorf("Failed to extract file desciptor, %v", err) 
    } 

    fd := fl.Fd() 

    argv0, err := exec.LookPath(os.Args[0]) 
    if err != nil { 
     return fmt.Errorf("Failed to execute lookpath, %v", err) 
    } 

    noCloseOnExec(fd) 

    files := make([]*os.File, fd+1) 
    files[syscall.Stdin] = os.Stdin 
    files[syscall.Stdout] = os.Stdout 
    files[syscall.Stderr] = os.Stderr 

    files[fd] = os.NewFile(fd, name) 

    wd, err := os.Getwd() 
    if err != nil { 
     return err 
    } 

    os.Setenv("GPROXY_FD", fmt.Sprintf("%d", fd)) 
    os.Setenv("GPROXY_PID", fmt.Sprintf("%d", syscall.Getpid())) 
    args := []string{"gproxy", "-debug", "start"} 
    _, err = os.StartProcess(argv0, args, &os.ProcAttr{ 
     Dir: wd, 
     Env: os.Environ(), 
     Files: files, 
    }) 

    return err 
} 

父終止

func termParentProcess() error { 
    pid := syscall.Getppid() 
    return syscall.Kill(pid, syscall.SIGTERM) 
} 
+0

那'termParentProcess'函數的上下文是什麼?有沒有任何定義的錯誤檢查? – JimB 2014-09-18 21:38:05

+0

這是我的錯我編輯它 – 2014-09-19 06:11:40

回答

2

長話短說,你不能叉,有一個很老的和持續的問題 here

你可以使用類似 https://github.com/icattlecoder/godaemon的東西,但父母不得不自己終止子女。

var isChild = flag.Bool("child", false, "parent pid") 

func main() { 
    flag.Parse() 
    var s string 
    if !*isChild { //parent 
     fmt.Println("forking") 
     files := make([]*os.File, 3) 
     files[syscall.Stdin] = os.Stdin 
     files[syscall.Stdout] = os.Stdout 
     files[syscall.Stderr] = os.Stderr 
     fmt.Println(os.StartProcess(os.Args[0], append(os.Args, "-child"), &os.ProcAttr{ 
      Dir: "/tmp", 
      Env: os.Environ(), 
      Files: files, 
     })) 
     fmt.Scan(&s) // block 
    } else { 
     ppid := os.Getppid() 
     fmt.Println("ppid", ppid, "kill:", syscall.Kill(ppid, syscall.SIGTERM)) 
     time.Sleep(5 * time.Second) 
     fmt.Println("child dying") 
    } 
} 
+0

我不認爲他真的想「叉」。他試圖執行一個新的進程(剛好是os.Args [0]),並且在將來的某個時間點殺死父進程。 – JimB 2014-09-18 21:35:29

+0

@JimB我誤解了這個問題,無論如何它是os.Getppid變得很時髦。 – OneOfOne 2014-09-18 22:19:02

+0

如果Getppid返回1,你的父母已經退出。 – JimB 2014-09-18 22:20:22

1

我的父進程上的一個術語信號不會終止的問題是因爲內部的for循環這不會中斷。我修復了for循環並讓主函數返回。如果在Go中主返回程序退出。對不起,因爲我自己的一個大錯誤打擾你們