zoukankan      html  css  js  c++  java
  • python 实现线程安全的单例模式

    单例模式是一种常见的设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

    比如,服务器的配置信息写在一个文件中online.conf中,客户端通过一个 Config 的类来读取配置文件的内容。如果在程序运行期间,有很多地方都需要使用配置文件的内容,那么每个调用配置文件的地方都会创建 Config的实例,这就导致系统中存在多个Config 的实例对象,在配置文件内容很多的情况下,我们就浪费了大量的内存做了同样的事。事实上,对于Config类我们在程序运行期间时只需要一个实例对象即可,这时单例模式就是最好的选择。

    python的模块就是天然的单例模式,这里我们使用修饰器来实现单例模式,以下是代码实现

    def Singleton(cls):
        instances = {}
    
        def get_instance(*args, **kw):
            if cls not in instances:
                instances[cls] = cls(*args, **kw)
            return instances[cls]
    
        return get_instance

    代码也很简单,将类传入单例修饰器中,如果该类还未生成实例(instances中不存在该类),那么就生成一个新的实例返回,并记录在instances中。如果已经instances中已经存在该类,那么直接返回实例instances[cls]。

    那么这段代码是完美的吗?答案是否定的,这段代码不是线程安全的。要实现线程安全需要配合锁的使用,只有占有锁的线程才能继续访问单例实例,看来我们需要再写一个修饰器来实现线程安全了,以下是完整的代码实现和简单的多线程测试用例。

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    import threading
    
    
    def synchronized(func):
        func.__lock__ = threading.Lock()
    
        def synced_func(*args, **kws):
            with func.__lock__:
                return func(*args, **kws)
    
        return synced_func
    
    
    def Singleton(cls):
        instances = {}
    
        @synchronized
        def get_instance(*args, **kw):
            if cls not in instances:
                instances[cls] = cls(*args, **kw)
            return instances[cls]
    
        return get_instance
    
    
    def worker():
        single_test = test()
        print "id----> %s" % id(single_test)
    
    
    @Singleton
    class test():
        a = 1
    
    if __name__ == "__main__":
        task_list = []
        for one in range(30):
            t = threading.Thread(target=worker)
            task_list.append(t)
    
        for one in task_list:
            one.start()
    
        for one in task_list:
            one.join()
  • 相关阅读:
    BOI 2002 双调路径
    BOI'98 DAY 2 TASK 1 CONFERENCE CALL Dijkstra/Dijkstra+priority_queue/SPFA
    USACO 2013 November Contest, Silver Problem 2. Crowded Cows 单调队列
    BOI 2003 Problem. Spaceship
    USACO 2006 November Contest Problem. Road Blocks SPFA
    CEOI 2004 Trial session Problem. Journey DFS
    USACO 2015 January Contest, Silver Problem 2. Cow Routing Dijkstra
    LG P1233 木棍加工 动态规划,Dilworth
    LG P1020 导弹拦截 Dilworth
    USACO 2007 February Contest, Silver Problem 3. Silver Cow Party SPFA
  • 原文地址:https://www.cnblogs.com/baiyb/p/8506438.html
Copyright © 2011-2022 走看看