在网上搜了一大圈,找到了一个独占文件的逻辑用了下,发出来和大家分享一下,写的还是不错的,我试了其它的一些方法,比如说 _, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, os.ModeExclusive) 这些乱起八糟的说明还是不能行,结果这套代码可以,那么就分享一下吧!
好吧直接上代码
package main
import (
"flag"
"fmt"
"os"
"syscall"
"time"
)
var filename string
var openSec int64
func main() {
flag.Int64Var(&openSec, "openSec", 60, "独占的秒数")
flag.StringVar(&filename, "filename", "D:/dd.txt", "需要独占打开得文件")
flag.Parse()
lockFile(filename, openSec)
}
func lockFile(filename string, openSec int64) error {
_, err := os.Stat(filename)
if err != nil {
return fmt.Errorf("打开文件[%s]失败,%v", filename, err)
}
p, err := syscall.UTF16PtrFromString(filename)
if err != nil {
return err
}
fd, err := syscall.CreateFile(p,
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
0,
nil,
syscall.OPEN_EXISTING, // syscall.CREATE_ALWAYS
syscall.FILE_ATTRIBUTE_NORMAL,
0,
)
if err != nil {
return err
}
time.Sleep(time.Second * time.Duration(openSec))
syscall.Close(fd)
return nil
}
以上代码是别的写的,那么我拿他来做了个函数封装,用于我的程序单进程锁
其实下面这些封装是不够完美的,相当于跑了一个独立线程来锁死文件,由于go还是不怎么熟练先凑合用了,如果你有更合适的方案欢迎发过来一起学习一下
func main() {
executablePath, _ := os.Executable()
path = filepath.Dir(executablePath)
if !lockProcess() {
s := "仅能执行一个进程"
writeToLogFile(s)
fmt.Println(s)
return
}
// 业务逻辑...
}
// 判断是否与其它实例并行
func lockProcess() bool {
filePath := filepath.Join(path, ".lock")
file, err := os.OpenFile(filePath, os.O_CREATE, 0666)
if err != nil {
return false
}
file.Close()
go func() {
err := lockFile(filePath)
if err != nil {
return
}
for {
time.Sleep(time.Hour * 1000)
}
}()
return true
}
func lockFile(filename string) error {
_, err := os.Stat(filename)
if err != nil {
return fmt.Errorf("打开文件[%s]失败,%v", filename, err)
}
p, err := syscall.UTF16PtrFromString(filename)
if err != nil {
return err
}
_, err = syscall.CreateFile(p,
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
0,
nil,
syscall.OPEN_EXISTING, // syscall.CREATE_ALWAYS
syscall.FILE_ATTRIBUTE_NORMAL,
0,
)
if err != nil {
return err
}
return nil
}
评论 (1)