python3 多线程 threading.local 代理_[Python 多线程] threading.local类 (六)

在使用threading.local()之前,先了解一下局部变量和全局变量。

局部变量:

import threading

import time

def worker():

x = 0

for i in range(100):

time.sleep(0.0001)

x += 1

print(threading.current_thread(),x)

for i in range(10):

threading.Thread(target=worker).start()

运行结果:

100

100

100

100

100

100

100

100

100

100

上面例子使用多线程,每个子线程完成不同的计算任务,x是局部变量。

每个子线程都要压栈,每个栈是独立的空间。每次压栈,局部变量x的作用域地址是不同的(线程独享),计算结果互不干扰。

全局变量:

使用global:

import threading

import time

x = 0

def worker():

global x

x = 0

for i in range(100):

time.sleep(0.0001)

x += 1

print(threading.current_thread(),x)

for i in range(10):

threading.Thread(target=worker).start()

运行结果:

888

908

930

937

941

947

949

955

962

964

上面例子中当主线程中x是全局变量时,就变成了公共资源(也就是同一个对象),每个子线程互相干扰,最终导致错误的计算结果。

Python提供了 threading.local 类,将这个类实例化得到一个全局对象,但是不同的线程使用这个对象存储的数据其它线程不可见(本质上就是不同的线程使用这个对象时为其创建一个独立的字典)。

使用threading.local() :

import threading

import time

# class A:

# def __init__(self,x):

# self.x = x

# a = A(0)

a = threading.local()#全局对象

def worker():

a.x = 0

for i in range(100):

time.sleep(0.0001)

a.x += 1

print(threading.current_thread(),a.x)

for i in range(10):

threading.Thread(target=worker).start()

运行结果:

100

100

100

100

100

100

100

100

100

100

每个子线程使用全局对象a,但每个线程定义的属性a.x是该线程独有的。

举一个错误的例子:,主线程中使用threading.local定义本地变量x,x在主线程中是独有的,子线程中就访问不到主线程的x的属性。

import threading

X='abc'

ctx=threading.local()

ctx.x=123 #主线程中定义x本地属性

print(ctx,type(ctx),ctx.x)

def work():

print(X)

print(ctx)

print(ctx.x) #子线程访问不到

print('Good job')

threading.Thread(target=work).start()

运行结果:

<_thread._local object at> 123

abc

Exception in thread Thread-1:

Traceback (most recent call last):

File "/Users/ihoney/Python/test_4.py", line 12, in work

print(ctx.x)

AttributeError: '_thread._local' object has no attribute 'x'

ctx全局对象对主线程和子线程都是可以使用的,主线程定义了属性x,但子线程在尝试访问属性x时,就相当于访问自己线程内的属性x,而自己线程并没有定义,就会抛出AttributeError异常:'_thread._local' object has no attribute 'x'。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值