/
single_instance.go
60 lines (47 loc) · 911 Bytes
/
single_instance.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// +build !windows
package common
import (
"fmt"
"io/ioutil"
"syscall"
)
func SingleInstane(pidfile string) {
if _, e := LockPidFile(pidfile); e != nil {
pid, _ := ioutil.ReadFile(pidfile)
panic(fmt.Errorf("Already running: [%v]", string(pid)))
}
}
func LockPidFile(pidfile string) (fd int, e error) {
fd, e = syscall.Open(pidfile, syscall.O_CREAT|syscall.O_RDWR, 0777)
if e != nil {
return
}
e = syscall.Flock(fd, syscall.LOCK_NB|syscall.LOCK_EX)
if e != nil {
return
}
e = syscall.Ftruncate(fd, 0)
if e != nil {
return
}
_, e = syscall.Write(fd, []byte(fmt.Sprintf("%d", syscall.Getpid())))
if e != nil {
return
}
return
}
func UnLockFile(fd int) (e error) {
if e = syscall.Flock(fd, syscall.LOCK_UN); e != nil {
return
}
if e = syscall.Close(fd); e != nil {
return
}
return
}
/*
func main() {
SingleInstane("/tmp/pid")
time.Sleep(100 * time.Second)
}
*/