threading.local学习

时间:2022-05-04 09:09:40

多线程抢占问题

import time
import threading obj = 5 def task(arg):
global obj
obj = arg
time.sleep(1)
print(obj) for i in range(6):
t = threading.Thread(target=task, args=(i,))
t.start() # 结果
5
5
5
5
5
5

  

threading.local对象避免线程抢占

为每个线程开辟一块内存空间,存储各自的数据

import time
import threading obj = threading.local() def task(arg):
global obj
obj.value = arg
time.sleep(1)
print(obj.value) for i in range(6):
t = threading.Thread(target=task, args=(i,))
t.start() # 结果
0
3
4
5
2
1

  

模拟threading.local

import time
import threading
# 获取线程的唯一标识
from threading import get_ident class Local():
def __init__(self):
self.storage = {}
def __setitem__(self, key, value):
ident = get_ident()
if ident in self.storage:
self.storage[ident][key] = value
else:
self.storage[ident] = {key:value}
def __getitem__(self, item):
ident = get_ident()
return self.storage[ident][item] obj = Local() def task(arg):
obj['num'] = arg
time.sleep(1)
print(obj['num']) for i in range(6):
t = threading.Thread(target=task, args=(i,))
t.start()

  

粒度精确到协程

为每个协程开辟一块内存空间,存储各自的数据

import time
import threading
try:
# 获取协程的唯一标识
from greenlet import getcurrent as get_ident
except Exception as e:
from threading import get_ident class Local():
def __init__(self):
self.storage = {}
def __setitem__(self, key, value):
ident = get_ident()
if ident in self.storage:
self.storage[ident][key] = value
else:
self.storage[ident] = {key:value}
def __getitem__(self, item):
ident = get_ident()
try:
return self.storage[ident][item]
except Exception as e:
return None obj = Local() def task(arg):
obj['num'] = arg
time.sleep(1)
print(obj['num']) for i in range(6):
t = threading.Thread(target=task, args=(i,))
t.start()