zoukankan      html  css  js  c++  java
  • python特殊线程:ThreadLocal

    1.ThreadLocal产生原因

      试想一个应用场景,例如flask中多个用户发起了多个http访问请求request,每个http请求就是一个独立线程,那么我们会有很多个线程,这些线程之间肯定要独立,才能保证每个请求的数据正确独立。

      那么,我们肯定每一个线程的request都是一个独立的局部变量对象

      1.传参方式:则将它作为参数传入函数处理,然而,随着业务和功能增多,可能有很多的函数来处理request,如果每个都用参数传递,未免太麻烦太多代码量,修改也麻烦,很不友好。

      2.不传参方式:但是如果使用全局变量,直接被函数处理,函数不用使用传参的方式,一个直观的的方法就是建立一个全局字典,保存进程 ID 到该进程局部变量的映射关系,运行中的线程可以根据自己的 ID 来获取本身拥有的数据。这样,就可以避免在函数调用中传递参数,如下示例:

    global_data = {}
    def show():
        cur_thread = threading.current_thread()
        print cur_thread.getName(), global_data[cur_thread]
     
    def thread_cal():
        cur_thread = threading.current_thread()
        global_data[cur_thread] = 0
        for _ in xrange(1000):
            global_data[cur_thread] += 1
        show() # Need no local variable. Looks good.
    ...

      保存一个全局字典,然后将线程标识符作为key,相应线程的局部数据作为 value,这种做法并不完美。首先,每个函数在需要线程局部数据时,都需要先取得自己的线程ID,略显繁琐。更糟糕的是,这里并没有真正做到线程之间数据的隔离,因为每个线程都可以读取到全局的字典,每个线程都可以对字典内容进行更改。

      3.ThreadLocal方式:为了更好解决这个问题,python 线程库实现了 ThreadLocal 变量(很多语言都有类似的实现,比如Java)。ThreadLocal 真正做到了线程之间的数据隔离,并且使用时不需要手动获取自己的线程 ID,如下示例:

    global_data = threading.local()
     
    def show():
        print threading.current_thread().getName(), global_data.num
     
    def thread_cal():
        global_data.num = 0
        for _ in xrange(1000):
            global_data.num += 1
        show()
     
    threads = []
    ...
     
    print "Main thread: ", global_data.__dict__ # {}

    上面示例中,全局变量global_data是一个ThreadLocal类对象,每个线程都可以通过 global_data.num 获得自己独有的数据,相互之间隔离互不影响,每个线程读取到的 global_data 都不同,好像global_data拥有很多个分身,真正做到线程之间的隔离,ThreadLocal对象像全局变量一样使用简单,但是却拥有局部变量的数据隔离特性,因此是一种很特殊和强大的类。

  • 相关阅读:
    谢谢博客-园,让我不再有开源AYUI的想法
    [ay原创作品]用wpf写了个模仿36Kr网站登录背景的效果
    [AY技术分享]WPF AYUI的高大上日历代码
    [C#] AY.WPF-图形编程-高中生为起点-研究报告1
    [Aaronyang]谈谈2015年AY对WPF全面技术总结40多篇WPF,炫到没朋友的AYUI来了
    C#人爱学不学9[C#5.0异步实例+WPF自己的MVVM Async应用 1/12]
    Ay.Framework.WPF 2.0建立项目到底有多快
    [aaronyang]WPF4.5
    Hystrix是什么
    通俗理解ZooKeeper是如何保证数据一致性的
  • 原文地址:https://www.cnblogs.com/DylanHooz/p/8446779.html
Copyright © 2011-2022 走看看