flask框架(十二):上下文管理***

情况一:单进程单线程

  基于全局变量实现。

情况二:单进程多线程

  基于threading.local对象。

  threading.local对象,用于为每个线程开辟一块空间来保存它独有的值。

# -*- coding: utf-8 -*-
# @Author : Felix Wang
# @time   : 2018/7/5 15:43

import threading

# 使用threading.local()时取到的是想要的值,数据操作是安全的
local_values = threading.local()


# 没有使用threading.local()时,取到的不是自己想要的值
# class Foo(object):
#     def __init__(self):
#         self.name=0
# local_values=Foo()

def func(num):
    local_values.name = num
    import time
    time.sleep(1)
    print(local_values.name, threading.current_thread().name)


for i in range(20):
    th = threading.Thread(target=func, args=(i,), name='线程{}'.format(str(i)))
    th.start()
单进程多线程情况

情况三:单进程单线程(多个协程),threading.local对象做不到。通过自定义类似threading.local对象

# -*- coding: utf-8 -*-
# @Author : Felix Wang
# @time   : 2018/7/5 16:06
import threading

try:
    from greenlet import getcurrent as get_ident  # 支持协程
except ImportError:
    try:
        from thread import get_ident
    except ImportError:
        from _thread import get_ident  # 获取线程的唯一标识


# 实现方式一
class Local(object):
    def __init__(self):
        self.storage = {}
        self.get_ident = get_ident

    def set(self, k, v):
        ident = self.get_ident()
        origin = self.storage.get(ident)
        if not origin:
            origin = {k: v}
        else:
            origin[k] = v
        self.storage[ident] = origin

    def get(self, k):
        ident = self.get_ident()
        origin = self.storage.get(ident)
        if not origin:
            return None
        return origin.get(k, None)


local_values = Local()


def task(num):
    local_values.set('name', num)
    import time
    time.sleep(1)
    print(local_values.get('name'), threading.current_thread().name)


for i in range(20):
    th = threading.Thread(target=task, args=(i,))
    th.start()


# 实现方式二
class Local2(object):
    def __init__(self):
        object.__setattr__(self, '__storage__', {})
        object.__setattr__(self, '__ident_func__', get_ident)
        # self.storage = {}
        # self.get_ident = get_ident

    def __getattr__(self, name):
        try:
            return self.__storage__[self.__ident_func__()][name]
        except KeyError:
            raise AttributeError(name)

    def __setattr__(self, key, value):
        ident = self.__ident_func__()
        storage = self.__storage__
        try:
            storage[ident][key] = value
        except KeyError:
            storage[ident] = {key: value}


local_values2 = Local2()


def task(num):
    local_values2.name = num
    import time
    time.sleep(1)
    print(local_values2.name, threading.current_thread().name)


for i in range(20, 40):
    th = threading.Thread(target=task, args=(i,))
    th.start()
自定义local对象

猜你喜欢

转载自www.cnblogs.com/felixwang2/p/9269330.html
今日推荐