美文网首页
多线程局部变量:threading.local()

多线程局部变量:threading.local()

作者: warmsirius | 来源:发表于2019-08-27 22:39 被阅读0次

参考博客

一、线程特定的数据

在线程中有些资源需要锁定(如Lock, RLock, Condition, Semaphore)以供多个线程使用,有些资源需要保护,以使它们对并非是这些资源的“所有者”隐藏。

local()函数回创建一个对象,它能够隐藏值,使其在不同线程中无法被看到,除非在某个线程中设置了这个属性。

  • 例1:
from threading import Thread


ret = -10

def task(args):
    global ret
    ret = args
    print(ret)


for i in range(10):
    t = Thread(target=task, args=(i,))
    t.start()

输出为

0
1
2
3
4
5
6
7
8
9
  • 例2:在print(i)之前,让程序执行某个io操作
from threading import Thread
import time


ret = -10

def task(args):
    global ret
    ret = args
    time.sleep(2)
    print(ret)


for i in range(10):
    t = Thread(target=task, args=(i,))
    t.start()

输出

9
9
9
9
9
9
9
9
9
9
  • 例3:使用threading.local()开创局部空间,保存当前变量
from threading import Thread, local
import time


ret = local()

def task(args):
    ret = args
    time.sleep(2)
    print(ret)


for i in range(10):
    t = Thread(target=task, args=(i,))
    t.start()

输出

0
1
2
3
4
5
8
7
6
9

threading.local()的作用就是为每个线程开辟一个独立的空间进行数据存储。

属性ret对所有线程都不可见,除非在某个线程中设置了这个属性,这个线程才能看见它。

二、初始化设置线程:所有线程开始时都有相同值

如果需要初始化设置以使所有线程在开始时都有相同的值,可以使用一个子类,并在init()中设置这些属性。

下面的代码对mysqlconn连接设置初始化,传入参数如下:

from threading import local
class MysqlConnManager(local):
    def __init__(self, host, port, db, usr, pwd):
        super().__init__()
        self._host = host
        self._port = port
        self._db = db
        self._usr = usr
        self._pwd = pwd
        self._conn = None

三、local源码

今天晚上脑子有点转不过来了,先贴上,过几天再看~

@contextmanager
def _patch(self):
    impl = object.__getattribute__(self, '_local__impl')
    try:
        dct = impl.get_dict()
    except KeyError:
        dct = impl.create_dict()
        args, kw = impl.localargs
        self.__init__(*args, **kw)
    with impl.locallock:
        object.__setattr__(self, '__dict__', dct)
        yield


class local:
    __slots__ = '_local__impl', '__dict__'

    def __new__(cls, *args, **kw):
        if (args or kw) and (cls.__init__ is object.__init__):
            raise TypeError("Initialization arguments are not supported")
        self = object.__new__(cls)
        impl = _localimpl()
        impl.localargs = (args, kw)
        impl.locallock = RLock()
        object.__setattr__(self, '_local__impl', impl)
        # We need to create the thread dict in anticipation of
        # __init__ being called, to make sure we don't call it
        # again ourselves.
        impl.create_dict()
        return self

    def __getattribute__(self, name):
        with _patch(self):
            return object.__getattribute__(self, name)

    def __setattr__(self, name, value):
        if name == '__dict__':
            raise AttributeError(
                "%r object attribute '__dict__' is read-only"
                % self.__class__.__name__)
        with _patch(self):
            return object.__setattr__(self, name, value)

    def __delattr__(self, name):
        if name == '__dict__':
            raise AttributeError(
                "%r object attribute '__dict__' is read-only"
                % self.__class__.__name__)
        with _patch(self):
            return object.__delattr__(self, name)

相关文章

  • Python 本地线程对象threading.local类

    在使用threading.local()之前,先了解一下局部变量和全局变量。 局部变量: 上面例子使用多线程,每个...

  • 多线程局部变量:threading.local()

    参考博客 多线程局部变量之threading.local()用法 一、线程特定的数据 在线程中有些资源需要锁定(如...

  • Flask拾遗笔记之上下文

    0x01 背景知识 threading.local() 通过threading.local()可以创建一个线程安全...

  • 一文详解Java中的ThreadLocal

    ThreadLocal用于多线程环境下每个线程存储和获取线程的局部变量,这些局部变量与线程绑定,线程之间互不影响。...

  • ThreadLocal

    1、局部变量传参 在多线程环境下,局部变量只有线程自己能看到, 不会影响其他线程, 而全局变量的修改必须加锁 。每...

  • 3.ThreadLocal源码

    ThreadLocal 属于java.lang,提供线程局部变量,用来处理多线程并发的。 使用ThreadLoca...

  • ThreadLocal

    import threading ​ local_school=threading.local() ​ def p...

  • 进程与线程

    3.多线程/进程&并发3.1 每个线程都有一个栈,保存自己的局部变量,多线程上锁保护全局变量和静态变量(存在.bs...

  • ThreadLocal

    在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见...

  • python使用ThreadLocal来设置线程内全局变量

    在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见...

网友评论

      本文标题:多线程局部变量:threading.local()

      本文链接:https://www.haomeiwen.com/subject/zloyectx.html