WorkerThread 设计
具体细节
threading.local
local的用法:
- 可以通过设置简单
threading.local,并设置相应的LocalManager来管理local - 还可以继承自
local 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
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
WorkerThread :该类继承自 threading.Thread, 为具体线程的类
threading.Thread特定用法:
- 在构造函数中传入一个callable对象,(函数或者其他)
- 在子类中重写
__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
注意
- 在python中对于真正的并行, 应当使用
multiprocessing模块, fork多个进行来并行的执行, 因为python 全局解释器锁的存在, python的线程提供interleving交叉, 但是实际上是连续串行执行,这仅仅对于有I/O操作时有效. - Thread-local 保存了线程拥有的局部变量,实现了线程变量的隔离, 比较好的实现,可以参考werkzeug中Thread-local的实现, 可以支持协程之间的私有数据 werkzeug
本文详细介绍了Python中的WorkerThread设计,利用`threading.local`实现线程本地变量,以及LocalManager的管理。WorkerThread类继承自`threading.Thread`,允许传入可调用对象并在特定线程中执行。需要注意的是,由于Python的全局解释器锁(GIL),线程并不能真正实现并行执行,适合于有I/O操作的情况。

1342

被折叠的 条评论
为什么被折叠?



