一、threading.loacl方法
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()
33760 29392 21292 5480 10516 29424 35968 10936 13416 28340 33644 34604 11892 15340 33676 9956 14248 31560 28108 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:Python36python.exe D:/my_flask/flask_third/test.py
23080
21992
26988
38836
13956
27856
24248
32728
12424
9140
26344
32020
9040
28664
32160
19468
20176
26072
17884
18232
可以看到,当我们把数据使用local对象时,不同之间线程数据是隔离的,赋值不会互相影响!
threading.local()这个方法的特点用来保存一个全局变量,但是这个全局变量只有在当前线程才能访问,
foo.num = num这条语句可以储存一个变量到当前线程,如果在另外一个线程里面再次对foo.num进行赋值,
那么会在另外一个线程单独创建内存空间来存储,也就是说在不同的线程里面赋值 不会覆盖之前的值,因为每个
线程里面都有一个单独的空间来保存这个数据,而且这个数据是隔离的,其他线程无法访问
这个东西可以用在那些地方呢,比如下载,现在都是多线程下载了,就像酷狗那样,可以同时下载很多首歌曲,那么
就可以利用这个方法来保存每个下载线程的数据,比如下载进度,下载速度之类的
所以 如果你在开发多线程应用的时候 需要每个线程保存一个单独的数据供当前线程操作,可以考虑使用这个方法,简单有效
其实这样的功能还有很多种方法可以实现,比如我们在主线程实例化一个dict对象,然后用线程的名字作为key,因为线程之间可以共享数据,
所以也可以实现相同功能,并且灵活性更多,不过代码就没那么优雅简洁了