-
-
Save smallnest/de6134e36b83fd6d215edf8db787235f to your computer and use it in GitHub Desktop.
Revisions
-
wrfly renamed this gist
Dec 12, 2018 . 1 changed file with 16 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -32,7 +32,11 @@ func main() { sig := make(chan os.Signal) signal.Notify(sig) for s := range sig { // see https://u.kfd.me/33 // SIGINT means graceful stop // SIGTERM means graceful [or not], cleanup something // SIGQUIT SIGKILL means immediately shutdown if s == syscall.SIGQUIT || s == syscall.SIGTERM { log.Printf("[%d] exit\n", pid) // make sure that parent can send signals to the children for _, child := range children { @@ -87,7 +91,7 @@ func main() { } // print children log.Printf("parent: PID=%d children=%v", pid, children) if len(children) == 0 && fork != 0 { log.Fatalf("no child avaliable, exit") } @@ -100,15 +104,17 @@ func main() { } } go func() { // parent will [only] notify children sig := make(chan os.Signal) signal.Notify(sig) for s := range sig { for _, child := range children { log.Printf("parent send %s to %d", s, child) syscall.Kill(child, s.(syscall.Signal)) } } }() } -
wrfly revised this gist
Dec 12, 2018 . 1 changed file with 85 additions and 36 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,72 +1,121 @@ package main import ( "flag" "fmt" "log" "os" "os/signal" "syscall" ) var ( daemon bool fork int children = []int{} ) func init() { flag.BoolVar(&daemon, "daemon", false, "run as daemon") flag.IntVar(&fork, "fork", 0, "fork how many sub process") flag.Parse() } func main() { pid := os.Getpid() ppid := os.Getppid() log.Printf("pid: %d, ppid: %d, args: %s", pid, ppid, os.Args) // handle exit for every process go func() { sig := make(chan os.Signal) signal.Notify(sig) for s := range sig { if s == syscall.SIGQUIT || s == syscall.SIGKILL { log.Printf("[%d] exit\n", pid) // make sure that parent can send signals to the children for _, child := range children { log.Printf("parent send %s to %d", s, child) syscall.Kill(child, s.(syscall.Signal)) } syscall.Exit(0) } } }() // only the parent process can do if _, isChild := os.LookupEnv("CHILD_ID"); !isChild { if daemon { if _, isDaemon := os.LookupEnv("DAEMON"); !isDaemon { daemonENV := []string{"DAEMON=true"} childPID, _ := syscall.ForkExec(os.Args[0], os.Args, &syscall.ProcAttr{ Env: append(os.Environ(), daemonENV...), Sys: &syscall.SysProcAttr{ Setsid: true, }, Files: []uintptr{0, 1, 2}, // print message to the same pty }) log.Printf("process %d run as daemon, %d will exit", childPID, pid) return // this return will give back the pty } log.Printf("daemon %d running and won't fork another daemon", os.Getpid()) } for i := 0; i < fork; i++ { args := append(os.Args, fmt.Sprintf("#child_%d_of_%d", i, os.Getpid())) childENV := []string{ fmt.Sprintf("CHILD_ID=%d", i), } pwd, err := os.Getwd() if err != nil { log.Fatalf("getwd err: %s", err) } childPID, _ := syscall.ForkExec(args[0], args, &syscall.ProcAttr{ Dir: pwd, Env: append(os.Environ(), childENV...), Sys: &syscall.SysProcAttr{ Setsid: true, }, Files: []uintptr{0, 1, 2}, // print message to the same pty }) log.Printf("parent %d fork %d", pid, childPID) if childPID != 0 { children = append(children, childPID) } } // print children log.Printf("parent: PID=%d children=%v", pid, children) if len(children) == 0 { log.Fatalf("no child avaliable, exit") } // set env for _, childID := range children { if c := os.Getenv("CHILDREN"); c != "" { os.Setenv("CHILDREN", fmt.Sprintf("%s,%d", c, childID)) } else { os.Setenv("CHILDREN", fmt.Sprintf("%d", childID)) } } // parent will only notify children sig := make(chan os.Signal) signal.Notify(sig) for s := range sig { for _, child := range children { log.Printf("parent send %s to %d", s, child) syscall.Kill(child, s.(syscall.Signal)) } } } // main sig := make(chan os.Signal) signal.Notify(sig) for s := range sig { log.Printf("PID[%d] got sig %s", pid, s) } } -
wrfly revised this gist
Dec 12, 2018 . 1 changed file with 16 additions and 16 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -17,16 +17,10 @@ func main() { ppid := os.Getppid() fmt.Printf("pid: %d, ppid: %d\n", pid, ppid) fmt.Println(fmt.Sprint(os.Args)) if strings.Contains(fmt.Sprint(os.Args), "#child_of_") { fmt.Println("child won't fork") } else { // only the parent process can do os.Args = append(os.Args, fmt.Sprintf("#child_of_%d", pid)) @@ -35,7 +29,7 @@ func main() { Sys: &syscall.SysProcAttr{ Setsid: true, }, Files: []uintptr{0, 1, 2}, }) fmt.Printf("fork %d\n", childPID) if childPID != 0 { @@ -50,7 +44,7 @@ func main() { } }() // notify children go func() { sig := make(chan os.Signal) signal.Notify(sig) @@ -59,14 +53,20 @@ func main() { fmt.Printf("send %s to %d\n", s, child) syscall.Kill(child, s.(syscall.Signal)) } } }() } // main sig := make(chan os.Signal) signal.Notify(sig) for s := range sig { fmt.Printf("%d got sig %s\n", pid, s) if s == syscall.SIGQUIT { time.Sleep(time.Second) fmt.Printf("%d exit\n", pid) syscall.Exit(0) } } } -
wrfly created this gist
Dec 12, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,72 @@ package main import ( "fmt" "os" "os/signal" "strings" "syscall" "time" ) var children = []int{} func main() { pid := os.Getpid() ppid := os.Getppid() fmt.Printf("pid: %d, ppid: %d\n", pid, ppid) go func() { sig := make(chan os.Signal) signal.Notify(sig) for s := range sig { fmt.Printf("%d got sig %s\n", pid, s) } }() if strings.Contains(strings.Join(os.Args, " "), "#child_of_") { fmt.Println("child fork return") } else { // only the parent process can do os.Args = append(os.Args, fmt.Sprintf("#child_of_%d", pid)) for i := 0; i < 5; i++ { childPID, _ := syscall.ForkExec(os.Args[0], os.Args, &syscall.ProcAttr{ Sys: &syscall.SysProcAttr{ Setsid: true, }, Files: []uintptr{1, 2}, }) fmt.Printf("fork %d\n", childPID) if childPID != 0 { children = append(children, childPID) } } // print children go func() { for { fmt.Printf("PID: %d children: %v\n", pid, children) time.Sleep(time.Second) } }() // notify children and handle exit go func() { sig := make(chan os.Signal) signal.Notify(sig) for s := range sig { for _, child := range children { fmt.Printf("send %s to %d\n", s, child) syscall.Kill(child, s.(syscall.Signal)) } if s == syscall.SIGQUIT { time.Sleep(time.Second) syscall.Exit(0) } } }() } time.Sleep(time.Minute) }