使用mutex实现应用程序单实例运行代码分享


在多种编程语言中,使用互斥锁(mutex)直接实现单实例运行可能不是最直接的方法,因为mutex通常用于线程或进程间的同步,而不是用于控制程序实例的数量。不过,我们可以结合文件锁(在文件系统中创建一个锁文件)和mutex(如果适用,比如在多线程环境中)来实现单实例运行。

以下是一个使用Python语言,通过文件锁(不是直接使用mutex)来实现单实例运行的示例代码:


import os
import fcntl
import sys

def singleton_decorator(cls):
    """
    单实例装饰器,通过文件锁实现。
    """
    class Singleton:
        _instance = None
        _lockfile = "/tmp/{}.lock".format(cls.__name__)

        def __new__(cls, *args, **kwargs):
            if not cls._instance:
                cls._instance = super(Singleton, cls).__new__(cls)
                # 尝试创建锁文件
                with open(cls._lockfile, 'w') as f:
                    try:
                        fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
                        # 锁文件创建成功,表示没有其他实例在运行
                        return cls._instance
                    except IOError:
                        # 锁文件已存在,表示已有实例在运行
                        print("Another instance of {} is already running.".format(cls.__name__))
                        sys.exit(1)
            return cls._instance

    return Singleton

@singleton_decorator
class MyApp:
    def __init__(self):
        print("MyApp instance created.")

    def run(self):
        print("MyApp is running.")

if __name__ == "__main__":
    app = MyApp()
    app.run()

注意:

- 这个示例使用了文件锁(通过`fcntl`模块)来模拟单实例运行。`fcntl.flock`用于在Unix-like系统上锁定文件。

- 如果你的应用需要在Windows上运行,你可能需要使用其他机制,如`msvcrt.locking`(但通常不推荐,因为它不如文件锁可靠),或者更常见的做法是使用第三方库,如`portalocker`。

- 装饰器`singleton_decorator`用于将任何类转换为单实例类。它创建了一个内部类`Singleton`,该类在实例化时尝试获取锁文件。如果锁文件已存在(表示已有实例在运行),则程序将退出。

- 请注意,这个实现依赖于文件系统,因此如果文件系统出现问题或程序被强制终止而没有正确释放锁,可能会导致锁文件残留。在实际应用中,你可能需要添加额外的逻辑来处理这种情况。