go中如何保证应用运行是单例的

Amosss · 2020-12-16 00:42:18 · 1898 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2020-12-16 00:42:18 的主题,其中的信息可能已经有所发展或是发生改变。

为了防止应用被重复打开,如何实现?有没有现有的框架或者库?


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1898 次点击  
加入收藏 微博
12 回复  |  直到 2020-12-22 09:59:41
focusonline
focusonline · #1 · 4年之前

其实解决这个办法就算不用框架也可以做到, 只是稍微消耗一点性能. 最简单的办法就是创建一个文件作为flag

zzustu
zzustu · #2 · 4年之前

不知道这个库有没有这个功能 https://github.com/kardianos/service

sanrentai
sanrentai · #3 · 4年之前

可以监听一个端口,如果失败直接退出。

anxk
anxk · #4 · 4年之前

pid文件?

helloh2o
helloh2o · #5 · 4年之前

应用到系统已经是系统进程了,可以根据查找进程名字判断。但楼上说的监听一个端口是简单实用的好办法。

Amosss
Amosss · #6 · 4年之前
focusonlinefocusonline #1 回复

其实解决这个办法就算不用框架也可以做到, 只是稍微消耗一点性能. 最简单的办法就是创建一个文件作为flag

异常崩溃了呢,单纯一个flag应该也不能判断是不是真的有进程存在吧。

focusonline
focusonline · #7 · 4年之前
AmosssAmosss #6 回复

#1楼 @focusonline 异常崩溃了呢,单纯一个flag应该也不能判断是不是真的有进程存在吧。

生成一个文件应该不会崩溃的啊? 是的, 还需要一些技巧, 比如一个时间的阈值.需要不停的touch这个文件刷新时间点等等 而且如果两个几乎同时启动的,可能还是没有用,这毕竟不是操作系统提供的同步方式.

focusonline
focusonline · #8 · 4年之前
AmosssAmosss #6 回复

#1楼 @focusonline 异常崩溃了呢,单纯一个flag应该也不能判断是不是真的有进程存在吧。

看一下这篇文章 https://blog.csdn.net/weiyuefei/article/details/77892871 os包里面有进程的函数可用.应该能解决你的问题了, 楼上已经提到了这个. 监听端口也可以,但是这个要浪费一个端口资源, 还是用查找进程的办法吧.

xmge
xmge · #9 · 4年之前
package prepare

import "syscall"

const (
    lf = "singleton.lock"
)

func singleton() {
    if fd, err := syscall.Open(lf, syscall.O_CREAT|syscall.O_RDONLY, 0644); err != nil {
        panic(err)
    } else if err := syscall.Flock(fd, syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
        panic(err)
    }
    return
}
stirlingx
stirlingx · #10 · 4年之前

共享内存 有名管道 socket等等

JGbooks
JGbooks · #11 · 4年之前
  1. 服务方式可以
  2. 运行前检测pid方式也可以
  3. 使用文件作为flag,例如syscall.Flock,这种方式很难控制.我测试是没有成功的,有成功的可以说下
Amosss
Amosss · #12 · 4年之前
xmgexmge #9 回复

```go package prepare import "syscall" const ( lf = "singleton.lock" ) func singleton() { if fd, err := syscall.Open(lf, syscall.O_CREAT|syscall.O_RDONLY, 0644); err != nil { panic(err) } else if err := syscall.Flock(fd, syscall.LOCK_EX|syscall.LOCK_NB); err != nil { panic(err) } return } ```

get了 谢谢。

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传