普通多线程修改同一数据
1 | import threading |
当多线程同时去修改同一个变量时,会出现数据不安全的情况,一般情况下会使用互斥锁来解决,代码如下:
1 | import threading |
threading.local对象
1 | import threading |
threading.local作用:为每个线程创建一个独立的空间,使得线程对自己的空间中的数据进行操作(数据隔离)。
问题:
如何获取一个线程的唯一标记? threading.get_ident()
根据字典自定义一个类似于threading.local功能?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import threading
import time
DIC = {}
def task(i):
ident = threading.get_ident()
if ident in DIC:
DIC[ident]["stack"] = i
else:
DIC[ident] = {"stack": i}
time.sleep(1)
print(DIC[ident]["stack"])
l = []
for i in range(10):
t = threading.Thread(target=task, args=(i,))
l.append(t)
t.start()
for p in l:
p.join()根据字典自定义一个为每个协程开辟空间进行存取数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import threading
import greenlet
import time
DIC = {}
def task(i):
# ident = threading.get_ident()
ident = greenlet.getcurrent()
if ident in DIC:
DIC[ident]["stack"] = i
else:
DIC[ident] = {"stack": i}
time.sleep(1)
print(DIC[ident]["stack"])
l = []
for i in range(10):
t = threading.Thread(target=task, args=(i,))
l.append(t)
t.start()
for p in l:
p.join()通过getattr/setattr 构造出来 threading.local的加强版(协程)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43import threading
import time
# 如果没有协程就使用线程ID
try:
import greenlet
get_ident = greenlet.getcurrent
except ImportError:
get_ident = threading.get_ident
class Local(object):
DIC = {}
# 获取
def __getattr__(self, item):
ident = get_ident()
if ident in self.DIC:
return self.DIC[ident].get(item)
return None
# 设置
def __setattr__(self, key, value):
ident = get_ident()
if ident in self.DIC:
self.DIC[ident][key] = value
else:
self.DIC[ident] = {key: value}
obj = Local()
def task(i):
obj.stack = i
time.sleep(1)
print(obj.stack)
l = []
for i in range(10):
t = threading.Thread(target=task, args=(i,))
l.append(t)
t.start()
for p in l:
p.join()