假如,开了十个线程并且做同样的一件事,他们需要带着自己的数据进来,完成事情后带着自己的数据出去。如果是并发,同时进来,他们的数据就会混乱。

一般情况,我们加锁就可以了,一个人先进来,先加锁,另一个人过来看到加锁了,就在外面等,等里面的人出来,自己进去加锁,这样就不会出现数据混乱的问题。

另一种解决方法就是threading.local()来解决问题。

先看下面这个现象

from threading import Thread

ret = -1  # 先定义一个变量

def task(arg):  # 写个任务,加个参数
global ret # 声明ret全局变量
ret = arg # 每一个线程进来到要改这个变量
print(ret) # 每个线程来,改了ret,然后取ret的值 for i in range(10): # i是线程的值,0 1 2 3 4 5 6 7 8 9
t = Thread(target=task, args=(i,)) # 开10个线程
t.start()
# 打印结果 0 1 2 3 4 5 6 7 8 9

这个程序开了10个线程,每个线程都执行了更改ret的值并获取ret更改后的值,如果非常快,他们取到的值都不一样.

如果让他们睡两秒再执行

from threading import Thread
import time ret = -1 # 先定义一个变量 def task(arg): # 写个任务,加个参数
global ret # 声明ret全局变量
ret = arg # 每一个线程进来到要改这个变量
time.sleep(2)
print(ret) # 每个线程来,改了ret,然后取ret的值 for i in range(10): # i是线程的值,0 1 2 3 4 5 6 7 8 9
t = Thread(target=task, args=(i,)) # 开10个线程
t.start()
# 打印结果 9 9 9 9 9 9 9 9 9 9

打印结果全是9

那么解决这个问题我们可以用threading.local()方法

from threading import Thread
from threading import local
import time
# 这是一个特殊的对象
ret = local() # 先实例化一个对象 def task(arg): # 写个任务,加个参数
ret = arg # 每一个线程进来都给他开辟一个独立的空间 单纯的threading.local()的作用就是这个
time.sleep(2)
print(ret) # 每个线程来,改了ret,然后取ret的值 for i in range(10): # i是线程的值,0 1 2 3 4 5 6 7 8 9
t = Thread(target=task, args=(i,)) # 开10个线程
t.start()
# 打印结果 0 3 2 5 7 9 8 4 1 6
threading.local()的作用就是为每个线程开辟一个独立的空间进行数据存储。

接下来我们自定义local对象
from threading import get_ident,Thread
import time storage = {} def set(k,v): # 来给storage设置值
ident = get_ident() # get_ident()能获取唯一标识,是一组数字
if ident in storage:
storage[ident][k] = v
else:
storage[ident] = {k:v} def get(k): # 来取storage的值
ident = get_ident()
return storage[ident][k] def task(arg):
set('val',arg)
v = get('val')
print(v) for i in range(10):
t = Thread(target=task,args=(i,))
t.start()

最新文章

  1. Memcached初识
  2. Hadoop各商业发行版之比较
  3. 实战p12文件转pem文件
  4. try-catch和throw,throws的区别
  5. Effective Java 47 Know and use the libraries
  6. RNA seq 两种计算基因表达量方法
  7. PC问题-VMware Workstation出现“文件锁定失败”
  8. libcurl断点下载
  9. IOS各类问题
  10. js的相关验证
  11. CF1153 F. Serval and Bonus Problem(dp)
  12. C++中的继承(3)作用域与重定义,赋值兼容规则
  13. Google 宣布在 4 月 1 日关闭站内搜索
  14. C-指针,二级指针,二维数组作为函数参数使用,C语言链表(详解)
  15. H - Gold Coins(2.4.1)
  16. JavaScript事件-this传递
  17. Excel VBA 从外部工作簿取数的5种方法
  18. SpringBoot整合SpringKafka实现生产者史上最简代码实现
  19. IoC基础例子
  20. 【git2】git+码云+webStrom

热门文章

  1. 9.4 dubbo异步调用原理
  2. 4种事务的隔离级别,InnoDB怎样巧妙实现?
  3. SQL列类型
  4. HTML解析库Gumbo简单使用记录
  5. Redis相关技巧
  6. Google 发布的15个 Android 性能优化典范
  7. 多分类-- ROC曲线
  8. unity, 在image effect shader中用_CameraDepthTexture重建世界坐标
  9. /Users/macbook/Library/Developer/Xcode/DerivedData/MapViewDemo: No such file or direc
  10. 假设分配给命令的连接位于本地挂起事务中,ExecuteReader 要求命令拥有事务。命令的 Transaction 属性尚未初始化