Python 程序单例运行

有些场景中,需要确保程序不被重复运行,也就是程序只在一个进程中被执行 (e.g., 微信)

程序单例运行的解决方案有:进程检测、端口抢占、文件锁

本文的代码采用了进程检测的手段,在主代码运行之前检测程序的运行状态 (check_running_status),如果当前程序已在一个进程中运行,则报错退出

check_running_status 的核心流程如下:

  • 根据当前 py 文件所在路径生成程序标识,并生成临时文件的名称
  • 读取临时文件中的进程信息,判断其所描述的进程是否存在;若存在则报错
  • 在临时文件中写入当前进程的信息
# ./test.py

def check_running_status():
    ''' 通过临时文件, 保证当前程序只在一个进程中被执行'''
    import os
    import psutil
    from pathlib import Path
    # 根据所运行的 py 文件生成程序标识
    exeid = (Path.cwd() / Path(__file__).name).resolve().as_posix().split(':')[-1].replace('/', '')
    f = (Path(os.getenv('tmp')) / f'py-{exeid}').with_suffix('.txt')
    # 读取文件, 并判断是否已有进程存在
    cur = psutil.Process()
    if f.is_file():
        try:
            _pid, time = f.read_text().split()
            other = psutil.Process(int(_pid))
        except:
            other, time = cur, cur.create_time() + 1
        # 退出: 文件所描述的进程仍然存在
        if other.create_time() == float(time):
            raise RuntimeError(f'The current program has been executed in process {other.pid}')
    # 继续: 创建文件描述当前进程
    f.write_text(' '.join(map(str, [cur.pid, cur.create_time()])))


if __name__ == '__main__':
    check_running_status()
    # ---------- 主程序 ----------
    input('原神启动')

将上述代码写于 ./test.py 中,再将以下代码写于 ./tmp.py 中

# ./tmp.py

import os

os.system('python test.py')

同时运行这两个程序,则可发现其中一个程序报错

Traceback (most recent call last):
  File "test.py", line 25, in <module>
    check_running_status()
  File "test.py", line 19, in check_running_status
    raise RuntimeError(f'The current program has been executed in process {other.pid}')
RuntimeError: The current program has been executed in process 28684

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荷碧TongZJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值