threading.local方法

先看如下示例:

import threading
import time


class Foo:
    pass


foo = Foo()


def func(num):
    foo.num = num
    time.sleep(1)  # 都睡一秒 还没来得及输出,就被后来的线程改了,所以等睡完之后,所有线程打印的num就都变为都后一次改得了
    print(foo.num, threading.current_thread().ident)


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

输出结果:

19 33760
19 29392
19 21292
19 5480
19 10516
19 29424
19 35968
19 10936
19 13416
19 28340
19 33644
19 34604
19 11892
19 15340
19 33676
19 9956
19 14248
19 31560
19 28108
19 5080

我们使用threading.local来存储num,再看看结果:

import threading
import time
from threading import local


class Foo:
    pass


# foo = Foo()
foo = local()


def func(num):
    foo.num = num
    time.sleep(1) 
    print(foo.num, threading.current_thread().ident)


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

结果:

C:\Python36\python.exe D:/my_flask/flask_third/test.py
1 23080
0 21992
3 26988
4 38836
2 13956
8 27856
6 24248
7 32728
5 12424
11 9140
9 26344
10 32020
12 9040
14 28664
13 32160
16 19468
15 20176
19 26072
17 17884
18 18232

可以看到,当我们把数据使用local对象时,不同之间线程数据是隔离的,赋值不会互相影响!

 

threading.local()这个方法的特点用来保存一个全局变量,但是这个全局变量只有在当前线程才能访问,

foo.num = num这条语句可以储存一个变量到当前线程,如果在另外一个线程里面再次对foo.num进行赋值,

那么会在另外一个线程单独创建内存空间来存储,也就是说在不同的线程里面赋值 不会覆盖之前的值,因为每个

线程里面都有一个单独的空间来保存这个数据,而且这个数据是隔离的,其他线程无法访问

 

这个东西可以用在那些地方呢,比如下载,现在都是多线程下载了,就像酷狗那样,可以同时下载很多首歌曲,那么

就可以利用这个方法来保存每个下载线程的数据,比如下载进度,下载速度之类的

 

所以  如果你在开发多线程应用的时候  需要每个线程保存一个单独的数据供当前线程操作,可以考虑使用这个方法,简单有效

其实这样的功能还有很多种方法可以实现,比如我们在主线程实例化一个dict对象,然后用线程的名字作为key,因为线程之间可以共享数据,

所以也可以实现相同功能,并且灵活性更多,不过代码就没那么优雅简洁了

posted @ 2018-10-15 20:12  Mr.GLH  阅读(312)  评论(0)    收藏  举报
Top↑