As a PHP development veteran. Used the command line to start/restart/stop operations such as nginx and PHP-FPM. Very impressed. If I were asked to develop such a system using C/C, I would definitely not have the energy to do it. However, since Golang entered my field of vision. I found it all very easy.
Go directly to the code:
package main import ( "os" "os/exec" "path/filepath" ) func main() { //判 断当其是否是子进程,当父进程return之后,子进程会被 系统1 号进程接管 if os.Getppid() != 1 { // 将命令行参数中执行文件路径转换成可用路径 filePath, _ := filepath.Abs(os.Args[0]) cmd := exec.Command(filePath, os.Args[1:]...) // 将其他命令传入生成出的进程 cmd.Stdin = os.Stdin // 给新进程设置文件描述符,可以重定向到文件中 cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Start() // 开始执行新进程,不等待新进程退出 return } }
Those who are familiar with the Linux system should know: the daemon process created by the user will be used by process No. 1 of the Linux system take over. In other words, the above code can only run on Linux systems. I have never played with Unix systems. Therefore, I cannot give specific suggestions.
I saw on the Internet that there are other ways to create a daemon process. However, I think only the source code method above seems good to me. and successfully used in projects.
For example:
os.StartProcess() 创建守护进程。 syscall.RawSyscall() 创建守护进程。
Only exec.Command
is the most advanced way to create a daemon process. Best encapsulated. It is recommended to use this test.
In point 1, we have successfully started a daemon process. However, we cannot use the kill command to end it. Then, start it again. Therefore, we have to use the industry’s professional approach: signals.
Any process running can receive the signal we send to it. There are many signals about Linux. You can search on Google for the keyword: Linux signal.
Go directly to the source code:
package main import "fmt" import "os" import "os/signal" import "syscall" func main() { // Go signal notification works by sending `os.Signal` // values on a channel. We'll create a channel to // receive these notifications (we'll also make one to // notify us when the program can exit). sigs := make(chan os.Signal, 1) done := make(chan bool, 1) // `signal.Notify` registers the given channel to // receive notifications of the specified signals. signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) // This goroutine executes a blocking receive for // signals. When it gets one it'll print it out // and then notify the program that it can finish. go func() { sig := <-sigs fmt.Println() fmt.Println(sig) done <- true }() // The program will wait here until it gets the // expected signal (as indicated by the goroutine // above sending a value on `done`) and then exit. fmt.Println("awaiting signal") <-done fmt.Println("exiting") }
There are three key points:
1) Register signal
2) Receive signal
3) Process signal.
As long as the creation of the daemon process and semaphore processing are integrated, commands can be implemented to manage the daemon process.
For more golang related technical articles, please visit the golang tutorial column!
The above is the detailed content of Analyze how Golang creates a daemon process and restarts smoothly. For more information, please follow other related articles on the PHP Chinese website!