Python 中的 TLS 以及 ContextVar

TLS

线程局部存储 TLS (Thread Local Storage)是一种多线程编程中的机制,它实现了在每个线程中独立存储一份数据的拷贝,使线程在访问特定数据时互不干扰,避免了多线程场景下的数据干扰和竞争。

其实现大概可以抽象成一个储物柜,在 Python 中通过 threading.local() 创建这个存储柜,每个线程相当于柜子的使用者,每个线程持有其中一个柜子,柜子里存放的是该线程独有的数据拷贝,这样就可以避免和其他线程的数据混淆。

一个简单的 example:

import time
import threading
from concurrent.futures import ThreadPoolExecutor

userName = threading.local()

def SessionThread(userName_in):
    time.sleep(0.5)
    t = threading.currentThread()
    print('Thread id : %d' % t.ident)
    print('Thread name : %s' % t.getName())
    userName.val = userName_in
    print('User name : %s' % userName.val)

pool = ThreadPoolExecutor()
for name in ['User1', 'User2']:
    pool.submit(SessionThread, name)

输出结果为:

Thread id : 123145562861568
Thread name : ThreadPoolExecutor-1_0
User name : User1
Thread id : 123145529282560
Thread name : ThreadPoolExecutor-1_1
User name : User2

在实际的项目应用中可以通过 TLS 实现一个参数透传的功能,使某些参数在不同模块的方法间的调用中不需要层层传递,更进一步地,可以通过 with 创建context,使得 with 内的代码块所调用到的函数都持有某一参数,具体可以参考 Towhee 中的param_scope实现。

ContextVar

TLS 实现的是多线程间的隔离,作用范围是一个线程的执行上下文,但如果是在异步的场景下可能会存在问题。因此我们需要实现协程内的隔离,Python 在3.7以后的版本提供了 contextvars 模块,用于创建 ContextVar 作用于一个异步任务的执行上下文,可以在多个协程中共享上下文变量,每个协程持有一份拷贝,不会相互干扰。
其用法与 TLS 类似,只是通过 set 和 get 赋值和获取:

import time
import contextvars
from concurrent.futures import ThreadPoolExecutor

username = contextvars.ContextVar("username", default='user')

def SessionThread(userName_in = None):
    time.sleep(0.1)
    t = threading.currentThread()
    print('Thread id : %d' % t.ident)
    print('Thread name : %s' % t.getName())
    if userName_in:
        username.set(userName_in)
    print('User name : %s' % username.get())

pool = ThreadPoolExecutor()
pool.submit(SessionThread)
for name in ['User1', 'User2']:
    pool.submit(SessionThread, name)

输出为:

Thread id : 123145531932672
Thread name : ThreadPoolExecutor-6_0
User name : user
Thread id : 123145498353664
Thread name : ThreadPoolExecutor-6_1
User name : User1
Thread id : 123145515143168
Thread name : ThreadPoolExecutor-6_2
User name : User2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值