zoukankan      html  css  js  c++  java
  • threading.local在flask中的用法

    一、介绍

    threading.local的作用:

    多个线程修改同一个数据,复制多份变量给每个线程用,为每个线程开辟一块空间进行数据的存储,而每块空间内的数据也不会错乱。

    二、不使用threading.local会导致数据错乱

    # 不用local
    from threading import Thread
    import time
    lqz = -1
    def task(arg):
        global lqz
        lqz = arg
        # time.sleep(2)
        print(lqz)
    
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()

    三、使用threading.local

    from threading import Thread
    from threading import local
    import time
    from threading import get_ident
    # 特殊的对象
    lqz = local()
    def task(arg):
        # 对象.val = 1/2/3/4/5
        lqz.value = arg
        time.sleep(2)
        print(lqz.value)
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()

    四、通过字典自定义threading.local(函数)

    from threading import get_ident,Thread
    import time
    storage = {}
    def set(k,v):
        ident = get_ident()
        if ident in storage:
            storage[ident][k] = v
        else:
            storage[ident] = {k:v}
    def get(k):
        ident = get_ident()
        return storage[ident][k]
    def task(arg):
        set('val',arg)
        v = get('val')
        print(v)
    
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()

    五、每个对象有自己的存储空间(字典)

    from threading import get_ident,Thread
    import time
    class Local(object):
        def __init__(self):
            object.__setattr__(self,'storage',{})
        def __setattr__(self, k, v):
            ident = get_ident()
            if ident in self.storage:
                self.storage[ident][k] = v
            else:
                self.storage[ident] = {k: v}
        def __getattr__(self, k):
            ident = get_ident()
            return self.storage[ident][k]
    obj = Local()
    def task(arg):
        obj.val = arg
        obj.xxx = arg
        print(obj.val)
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()

    六、兼容线程和协程

    try:
        from greenlet import getcurrent as get_ident
    except Exception as e:
        from threading import get_ident
    from threading import Thread
    import time
    class Local(object):
        def __init__(self):
            object.__setattr__(self,'storage',{})
        def __setattr__(self, k, v):
            ident = get_ident()
            if ident in self.storage:
                self.storage[ident][k] = v
            else:
                self.storage[ident] = {k: v}
        def __getattr__(self, k):
            ident = get_ident()
            return self.storage[ident][k]
    obj = Local()
    def task(arg):
        obj.val = arg
        obj.xxx = arg
        print(obj.val)
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()
  • 相关阅读:
    [网络收集]用户自定义控件中如何引入样式文件
    [网络收集]在应用程序级别之外使用注册为 allowDefinition='MachineToApplication'
    [网络收集]索引超出范围。必须为非负值并小于集合大小,参数名: index。
    Ubiquitous Religions(无处不在的宗教)
    for_each
    Is It A Tree
    SAStruts/S2JDBC ネストしたプロパティの画面部品
    はじめてのSAStruts 3週目
    はじめてのSAStruts 2週目
    DB2で「SELECT ... FOR UPDATE」のロックを検証
  • 原文地址:https://www.cnblogs.com/angelyan/p/10896005.html
Copyright © 2011-2022 走看看