情况一:单进程单线程
基于全局变量实现。
情况二:单进程多线程
基于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()
自定义local对象