Golang利用Pid实现单进程模型

需求

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

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

Golang 在Linux平台实现。

流程图

Y
Y
N
N
读取失败
读取Pid文件
该Pid进程是否运行
进程名字是否一致
进程已存在
进程不存在
程序退出
覆盖写入当前Pid至文件
程序继续运行

实现

// 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值