需求
一个中间件,同时只能运行一个。
使用读写Pid(进程号)文件的方式实现单进程模型。
Golang 在Linux平台实现。
流程图
实现
// go mod init turtle
package main
import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
)
func main() {
println("Turtle is Running...")
err := CheckSingleProcess("/root/ttt/turtlepid", "turtle")
if err != nil {
fmt.Println(err)
return
}
for {
time.Sleep(time.Duration(5) * time.Second)
}
}
func CheckSingleProcess(pid_path string, proc_name string) error {
buf, err := ioutil.ReadFile(pid_path)
if err == nil {
pid := strings.TrimSpace(string(buf))
err = CheckProcExist(pid, proc_name)
if err != nil {
return err // 已存在该进程
}
}
err = os.MkdirAll(filepath.Dir(pid_path), os.FileMode(0755))
if err != nil {
return err
}
pid := fmt.Sprintf("%d", os.Getpid())
err = ioutil.WriteFile(pid_path, []byte(pid), 0644)
return err
}
func CheckProcExist(pid string, proc_name string) error {
pid_dir := filepath.Join("/proc", pid) // /proc/$pid
pid_status := filepath.Join(pid_dir, "status") // /proc/$pid/status
_, err := os.Stat(pid_dir)
if err != nil {
return nil // not exist
}
f, err := os.Open(pid_status)
if err != nil {
return nil // not exist
}
r := bufio.NewReader(f)
buf, _, err := r.ReadLine()
if err != nil {
return nil
}
// /proc/$pid/status文件第一行就是 name: turtle
nameline := strings.TrimSpace(string(buf))
index := strings.Index(nameline, ":")
name := strings.TrimSpace(nameline[index+1:])
if name == proc_name {
return errors.New("there is already a Process")
}
return nil
}
测试
启动一个进程
root@ubuntu:~# ./turtle
Turtle is Running...
检查Pid
root@ubuntu:~# ps -ef| grep turtle
root 102084 91610 0 17:48 pts/1 00:00:00 ./turtle
root 102115 92060 0 17:50 pts/2 00:00:00 grep --color=auto turtle
root@ubuntu:~#
root@ubuntu:~# cat /root/ttt/turtlepid
102084
再启动一个进程
root@ubuntu:~# ./turtle
Turtle is Running...
there is already a Process
关闭第一个进程,再启动
root@ubuntu:~# ./turtle
Turtle is Running...
^C
root@ubuntu:~# ./turtle
Turtle is Running...
检查Pid
root@ubuntu:~# ps -ef|grep turtle
root 102131 91610 0 17:53 pts/1 00:00:00 ./turtle
root 102140 92060 0 17:54 pts/2 00:00:00 grep --color=auto turtle
root@ubuntu:~#
root@ubuntu:~# cat /root/ttt/turtlepid
102131