Python thread local
class Widgt(object):
pass import threading
def test():
local_data = threading.local()
# local_data = Widgt()
local_data.x = 1 def thread_func():
print('Has x in new thread: %s' % hasattr(local_data, 'x'))
local_data.x = 2 t = threading.Thread(target = thread_func)
t.start()
t.join()
print('x in pre thread is %s' % local_data.x) if __name__ == '__main__':
test()
try:
from thread import _local as local
except ImportError:
from _threading_local import local
class _localbase(object):
__slots__ = '_local__key', '_local__args', '_local__lock' def __new__(cls, *args, **kw):
self = object.__new__(cls)
key = '_local__key', 'thread.local.' + str(id(self)) # 产生一个key,这个key在同一个进程的多个线程中是一样的
object.__setattr__(self, '_local__key', key)
object.__setattr__(self, '_local__args', (args, kw))
object.__setattr__(self, '_local__lock', RLock()) # 可重入的锁 if (args or kw) and (cls.__init__ is object.__init__):
raise TypeError("Initialization arguments are not supported") # We need to create the thread dict in anticipation of
# __init__ being called, to make sure we don't call it
# again ourselves.
dict = object.__getattribute__(self, '__dict__')
current_thread().__dict__[key] = dict # 在current_thread这个线程唯一的对象的—__dict__中加入 key return self def _patch(self):
key = object.__getattribute__(self, '_local__key')
d = current_thread().__dict__.get(key) # 注意 current_thread 在每一个线程是不同的对象
if d is None: # 在新的线程第一次调用时
d = {} # 一个空的dict !!!
current_thread().__dict__[key] = d
object.__setattr__(self, '__dict__', d) # 将实例的__dict__赋值为 线程独立的一个字典 # we have a new instance dict, so call out __init__ if we have
# one
cls = type(self)
if cls.__init__ is not object.__init__:
args, kw = object.__getattribute__(self, '_local__args')
cls.__init__(self, *args, **kw)
else:
object.__setattr__(self, '__dict__', d) class local(_localbase): def __getattribute__(self, name):
lock = object.__getattribute__(self, '_local__lock')
lock.acquire()
try:
_patch(self) # 这条语句执行之后,self.__dict__ 被修改成了线程独立的一个dict
return object.__getattribute__(self, name)
finally:
lock.release()
import threading
from _threading_local import local
def test():
local_data = local()
local_data.x = 1
print 'id of local_data', id(local_data) def thread_func():
before_keys = threading.current_thread().__dict__.keys()
local_data.x = 2
after = threading.current_thread().__dict__
# print set(after.keys()) - set(before.keys())
print [(e, v) for (e, v) in after.iteritems() if e not in before_keys] t = threading.Thread(target = thread_func)
t.start()
t.join()
print('x in pre thread is %s' % local_data.x) if __name__ == '__main__':
test()
输出:
id of local_data 40801456
[(('_local__key', 'thread.local.40801456'), {'x': 2})]
class GeventServer(ServerAdapter):
""" Untested. Options: * See gevent.wsgi.WSGIServer() documentation for more options.
""" def run(self, handler):
from gevent import pywsgi, local
if not isinstance(threading.local(), local.local): #注意这里
msg = "Bottle requires gevent.monkey.patch_all() (before import)"
raise RuntimeError(msg)
if self.quiet:
self.options['log'] = None
address = (self.host, self.port)
server = pywsgi.WSGIServer(address, handler, **self.options)
if 'BOTTLE_CHILD' in os.environ:
import signal
signal.signal(signal.SIGINT, lambda s, f: server.stop())
server.serve_forever()
这个小插曲其实也反映了monkey-patch的一些优势与劣势。其优势在于不对源码修改就能改变运行时行为,提高性能;同时 ,对于缺乏经验或者对patch细节不了解的人来说,会带来静态代码与运行结果之间的认知差异。
Python thread local的更多相关文章
- TLS 与 python thread local
TLS 先说TLS( Thread Local Storage),wiki上是这么解释的: Thread-local storage (TLS) is a computer programming m ...
- Python - python3.7新增的contextvars vs Thread local(threading.local)
总结 和threading.local()类似.Python3.7新增. thread.local(): 不同线程,同一个变量保存不同的值. contextvars: 不同上下文,同一个变量保存不同的 ...
- [Python]threading local 线程局部变量小測试
概念 有个概念叫做线程局部变量.一般我们对多线程中的全局变量都会加锁处理,这样的变量是共享变量,每一个线程都能够读写变量,为了保持同步我们会做枷锁处理.可是有些变量初始化以后.我们仅仅想让他们在每一个 ...
- Java进阶(七)正确理解Thread Local的原理与适用场景
原创文章,始自发作者个人博客,转载请务必将下面这段话置于文章开头处(保留超链接). 本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ Th ...
- 线程TLAB局部缓存区域(Thread Local Allocation Buffer)
TLAB(Thread Local Allocation Buffer) 1,堆是JVM中所有线程共享的,因此在其上进行对象内存的分配均需要进行加锁,这也导致了new对象的开销是比较大的 2,Sun ...
- Java Thread Local – How to use and code sample(转)
转载自:https://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/ Thread Local ...
- Python Thread related
1.Thread.join([timeout]) Wait until the thread terminates. This blocks the calling thread until the ...
- python thread的join方法解释
python的Thread类中提供了join()方法,使得一个线程可以等待另一个线程执行结束后再继续运行.这个方法还可以设定一个timeout参数,避免无休止的等待.因为两个线程顺序完成,看起来象一个 ...
- 【Python@Thread】queue模块-生产者消费者问题
python通过queue模块来提供线程间的通信机制,从而可以让线程分项数据. 个人感觉queue就是管程的概念 一个生产者消费者问题 from random import randint from ...
随机推荐
- minor gc 和 full gc
JAVA中关于GC的分析中,需要搞清楚,GC线程在什么时候,对什么东西,做了什么操作. 1-在什么时候 首先需要知道,GC分为minor GC和full GC,JAVA内存分为新生代和老年代,新生代中 ...
- 使用Emacs中的org-mode写cnblogs之图片插入
.title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium ...
- 关于css中的border
我一直以为css中的border是正方形的 像这样 因为我平时用的时候都是 border:1px solid #000,都是同一个颜色所以看不出来 当我给每一个边分别设置颜色的时候才发现 他们是以梯形 ...
- MVC笔记2:mvc+jquery.validate.js 进行前端验证
1.引用如下js和css 代码 <link href="@Url.Content("~/Content/Site.css")" rel="sty ...
- 2.7. 属性的各种设置选项(Core Data 应用程序实践指南)
可供配置的选项根据属性类型的不同有所变化,并不是每一种属性都能配置下列选项 Transient:勾选该选项,表示该属性不写入“持久化存储区”,这听起来很奇怪,但有时候,只需要把特性留在托管对象上下文就 ...
- jQuery插件开发详解
我们该如何扩展jQuery呢?主要可以通过下面2个来扩展:$.extend 和 $.fn $.extend如果把jQuery当成一个类,$.extend相当于为该类添加了静态方法extend. < ...
- 纯代码实现CSS圆角
我这里说的是纯代码,是指的不使用图片实现圆角,图片实现圆角,这里就不说了. 纯代码实现圆角主要有3种方法: 第一种:CSS3圆角 #chaomao{ border-radius:2px 2 ...
- 测试web网站兼容性的方法
随着操作系统,浏览器越来越多样性,导致软件兼容性测试在目前软件测试领域占有很重要的地位,无论是B/S架构还是C/S架构的软件都需要进行兼容性测试,为了充分保证产品的平台无关性,使用户充分感受到软件的友 ...
- There is no getter for property named 'userId' in 'class java.lang.String'
[ERROR] 2017-01-18 04:37:06:231 cn.dataenergy.common.CenterHandlerExceptionResolver (CenterHandlerEx ...
- java服务器获取客户端ip
在写服务端代码时,有时需要对客户端ip做认证,比如限制只有某些ip能访问,或者1个ip1天只能访问几次.最近就碰到个需要限制ip的情况,从网上找了一些服务器获取客户端ip的方法,说的都不太完善,这里整 ...