0%

Go滚动重启

1. 应用场景

例如当我们更新了配置文件,但是我们不想停止程序重启

2. 实现思想

在我们检测到配置文件更改时,进行进程替换,但如果我们开启子进程,杀死父进程,会产生孤儿进程

3. 破局

查询资料,发现了syscall.Exec函数,文档中这样描写到Exec invokes the execve(2) system call.,那么这个execve(2)的系统调用有什么作用呢?

execve() executes the program referred to by pathname. This causes the program that is currently being run by the calling process to be replaced with a new program, with newly initialized stack, heap, and (initialized and uninitialized) data segments.
翻译一下:
execve() 执行路径名引用的程序。 这会导致当前正在由调用进程运行的程序被新程序替换,新程序具有新初始化的堆栈、堆和(已初始化和未初始化的)数据段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
"fmt"
"log"
"os"
"syscall"
)

func main() {
if err := syscall.Exec("/bin/ls", []string{"ls", "-l", "-a"}, os.Environ()); err != nil {
log.Println("syscall.Exec报错了: ", err.Error())
}
fmt.Println("我还没上车呢。。。。")
}

output1
output2

可以发现,当我们成功执行syscall.Exec时,我们的程序被替换成了ls -al,所以最后一行输出语句并没有执行


chatgpt对于syscall.Exec的回答
chatgpt syscall exec