V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
raw0xff

golang 如何判断自身已被执行?

  •  
  •   raw0xff · May 6, 2022 · 5228 views
    This topic created in 1455 days ago, the information mentioned may be changed or developed.

    网上暂时找到两个方法:

    1. 进程运行时检查当前目录下有没有 PID 文件,有就是重复执行。没有的话就获取当前 PID 保存在当前目录。
    2. os.Getenv 获取环境变量,为空就是首次执行,然后写入环境变量。不为空就是重复执行。

    第一种方式问题是需要文件锁,而 win 不支持文件锁。 第二种不知道 win 是否支持,但是如果进程启动后被 kill 掉,那么环境变量依然存在,还会被视为重复运行。

    我想实现如果首次执行就后台运行,开始监听端口,等待被调用业务函数。 如果已经执行,就显示菜单,等待输入业务指令。

    请教大佬还有哪些办法可以判断自身已经被执行?

    hash 自身程序?然后在进程里对比?是不是太极端了?进程里找程序名会不会太不严谨?求教!

    21 replies    2022-05-07 19:33:34 +08:00
    statumer
        1
    statumer  
       May 6, 2022 via iPhone
    xyjincan
        2
    xyjincan  
       May 6, 2022 via Android
    绑定一个端口
    Livid
        3
    Livid  
    MOD
    PRO
       May 6, 2022   ❤️ 2
    如果有配置文件,那么可以把 PID 位置在配置文件里指定,端口也可以在配置文件里指定。

    如果端口或者 PID 存在,并且端口上能够正确应答,那就可以认为是已经在运行了。
    snowlyg
        4
    snowlyg  
       May 6, 2022   ❤️ 1
    喊它一声,看它敢不敢答应
    GuuJiang
        5
    GuuJiang  
       May 6, 2022 via iPhone
    mutex
    PolarBears
        6
    PolarBears  
       May 6, 2022
    获取自身进程路径然后找找系统进程有没有里有没有相同路径
    est
        7
    est  
       May 6, 2022
    windows 有一个机制好像会生成一个唯一的 GUID 然后可以保证单例运行。

    https://www.c-sharpcorner.com/UploadFile/f9f215/how-to-restrict-the-application-to-just-one-instance/
    bruce0
        9
    bruce0  
       May 6, 2022
    一看看过 C++的相关东西, 有一次无意听到我 CTO 说过 常用的有检查文件,每次成功启动在指定目录写一个文件; 还一种方式就是监听端口, 但是我想了一下 这个不能使用 端口复用这个特性
    jinliming2
        10
    jinliming2  
       May 6, 2022
    windows 下可以通过 CreateMutex 创建互斥量来做进程间的互斥访问。所以可以条件编译,windows 下用 windows 的方式,linux 下用 linux 的方式。

    另外,既然你需要在执行后监听端口,那么如果没有开启 SO_REUSEPORT 的话,应该第二个进程在尝试监听同一个端口的时候就会失败,捕获这个 error 不就可以实现互斥了吗?
    hhaobao
        11
    hhaobao  
       May 6, 2022
    CreateMutexW, 具体代码就不贴了, 自己看一些网游 ,还有一些不准多开的软件, 还有比如微信, 你用 process hacker 把它的 mutex 关了就可以多开了
    lysS
        12
    lysS  
       May 6, 2022
    单例是吧?写个文件,检查进程号啥的都行。

    或者用系统接口,https://www.csdn.net/tags/MtTaAg2sNTcyODQ2LWJsb2cO0O0O.html
    jasonkayzk
        13
    jasonkayzk  
       May 6, 2022
    绑定到一个固定的端口,第二个服务就起不来了
    kosgug
        14
    kosgug  
       May 6, 2022 via iPhone
    @snowlyg 哈哈哈,人才
    raw0xff
        16
    raw0xff  
    OP
       May 6, 2022
    @Livid 有配置文件,正在按你说的尝试,应该可以


    @snowlyg 简明扼要通俗易懂!


    @PolarBears 不严谨,如果是不同路径的相同程序呢


    @est 谢谢我瞅瞅先


    @bruce0 检查端口会有两种可能,一种是已运行,另一种是端口被其他程序占用了


    @jinliming2 @jasonkayzk 监听的端口不固定,而且允许用户自定义监听端口,所以不能作为唯一判断。


    @hhaobao mark 一下,稍后学习



    @lysS @czyt 感谢
    biubiuF
        17
    biubiuF  
       May 6, 2022
    每次启动尝试一下删除文件,删除成功就创建一个新的文件并且 hold 住,然后启动实例
    Baloneo
        18
    Baloneo  
       May 6, 2022
    设置进程名
    zjj19950716
        19
    zjj19950716  
       May 6, 2022
    github.com/gofrs/flock
    用的这个文件锁,有 win 实现
    sdrzlyz
        20
    sdrzlyz  
       May 7, 2022
    启 udp...然后做好应答。
    另一个启的时候,广播含一嗓子,有正确应答就是已经启动了

    狗头保命
    Akiya
        21
    Akiya  
       May 7, 2022 via iPhone
    一般是用文件锁
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1193 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 113ms · UTC 23:19 · PVG 07:19 · LAX 16:19 · JFK 19:19
    ♥ Do have faith in what you're doing.