1. 程式人生 > >python 實現執行緒安全的單例模式

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()