情况一:单进程单线程
基于全局变量实现。
情况二:单进程多线程
基于threading.local对象。
threading.local对象,用于为每个线程开辟一块空间来保存它独有的值。
# -*- coding: utf-8 -*- # @Author : Felix Wang # @time : 2018/7/5 15:43 import threading # 使用threading.local()时取到的是想要的值,数据操作是安全的 local_values = threading.local() # 没有使用threading.local()时,取到的不是自己想要的值 # class Foo(object): # def __init__(self): # self.name=0 # local_values=Foo() def func(num): local_values.name = num import time time.sleep(1) print(local_values.name, threading.current_thread().name) for i in range(20): th = threading.Thread(target=func, args=(i,), name='线程{}'.format(str(i))) th.start()
情况三:单进程单线程(多个协程),threading.local对象做不到。通过自定义类似threading.local对象
# -*- coding: utf-8 -*- # @Author : Felix Wang # @time : 2018/7/5 16:06 import threading try: from greenlet import getcurrent as get_ident # 支持协程 except ImportError: try: from thread import get_ident except ImportError: from _thread import get_ident # 获取线程的唯一标识 # 实现方式一 class Local(object): def __init__(self): self.storage = {} self.get_ident = get_ident def set(self, k, v): ident = self.get_ident() origin = self.storage.get(ident) if not origin: origin = {k: v} else: origin[k] = v self.storage[ident] = origin def get(self, k): ident = self.get_ident() origin = self.storage.get(ident) if not origin: return None return origin.get(k, None) local_values = Local() def task(num): local_values.set('name', num) import time time.sleep(1) print(local_values.get('name'), threading.current_thread().name) for i in range(20): th = threading.Thread(target=task, args=(i,)) th.start() # 实现方式二 class Local2(object): def __init__(self): object.__setattr__(self, '__storage__', {}) object.__setattr__(self, '__ident_func__', get_ident) # self.storage = {} # self.get_ident = get_ident def __getattr__(self, name): try: return self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) def __setattr__(self, key, value): ident = self.__ident_func__() storage = self.__storage__ try: storage[ident][key] = value except KeyError: storage[ident] = {key: value} local_values2 = Local2() def task(num): local_values2.name = num import time time.sleep(1) print(local_values2.name, threading.current_thread().name) for i in range(20, 40): th = threading.Thread(target=task, args=(i,)) th.start()