Golang利用Pid实现单进程模型

需求

一个中间件,同时只能运行一个。

使用读写Pid(进程号)文件的方式实现单进程模型。

Golang 在Linux平台实现。

流程图

Y

Y

N

N

读取失败

读取Pid文件

该Pid进程是否运行

进程名字是否一致

进程已存在

进程不存在

程序退出

覆盖写入当前Pid至文件

程序继续运行

实现


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)
    pid_status := filepath.Join(pid_dir, "status")

    _, err := os.Stat(pid_dir)
    if err != nil {
        return nil
    }
    f, err := os.Open(pid_status)
    if err != nil {
        return nil
    }
    r := bufio.NewReader(f)
    buf, _, err := r.ReadLine()
    if err != nil {
        return nil
    }

    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

Original: https://blog.csdn.net/jacicson1987/article/details/128346224
Author: 小湿哥
Title: Golang利用Pid实现单进程模型

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/723258/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球