local
的用法:
threading.local
,并设置相应的LocalManager
来管理locallocal class
, 这种方法可以很有效的实现local的默认值, 方法, 初始化. 注意如果定义了 __init__
函数, 将会在每个特定的线程中进行 __init__
函数的调用,这对于初始化每一个线程的字典来说非常的重要threading.local()
:类表示线程本地变量. 线程本地变量对于特定的线程不同. 管理线程本地变量threading.local
, 如 mydata = threading.local() mydata.x = 1
继承自threading.local
的用法如下(具体见官方源码):
class MyLocal(local):
number = 2
initialized = False
def __init__(self, **kw):
if self.initialized:
raise SystemError('__init__ called two many times')
self.initialized = True
self.__dict__.update(kw)
def squared(self):
return self.number**2
subclasses 可以定义 __slots__
, 但是并不是线程本地变量, 而是通过线程共享
LocalManager
:该类用来管理本地线程变量,中的具体字段.
class LocalManager(object):
def __init__(self, local_obj):
self.local_obj = local_obj
def to_dict(self):
rv = {}
for field in self.fields:
rv[field] = getattr(self, field, None)
return rv
def update(self, **kwargs):
for field, value in kwargs.iteritems():
setattr(self, field, value)
def clear(self):
self.local_obj.__dict__.clear()
def __getattr__(self, name):
return getattr(self.local_obj, name, None)
def __setattr__(self, name, value):
if name in self.fields:
return setattr(self.local_obj, name, value)
else:
super(LocalManager, self).__setattr__(name, value)
创建本地线程变量
worker_local = LocalManager(_local)
仅仅这样用, 对于不同的线程, 其中的 worker_local
不同
WorkerThread
:该类继承自 threading.Thread
, 为具体线程的类
threading.Thread
特定用法: __init__
和 run
方法 get_result(self)
方法类似与 requests.raise_for_status()
: 先存异常状态码,再抛出异常class WorkerThread(threading.Thread):
def __init__(self, func, *args, **kwargs):
super(WorkerThread, self).__init__()
self.func = func
self.args = args
self.kwargs = kwargs
self.exception = None
self.result = None
self.request_params = worker_local.to_dict()
def run(self):
worker_local.update(**self.request_params)
try:
self.result = self.func(*self.args, **self.kwargs)
except Exception as e:
self.exception = e
log_exception('worker', e)
def get_result(self):
if self.exception is not None:
raise self.exception
else:
return self.result
multiprocessing
模块, fork多个进行来并行的执行, 因为python 全局解释器锁的存在, python的线程提供interleving
交叉, 但是实际上是连续串行执行,这仅仅对于有I/O操作时有效.深入理解Thread-local