Python_关于多线程下变量赋值取值的一点研究
关于多线程下变量赋值取值的一点研究
by:授客 QQ:1033553122
1.代码实践1
#!/usr/bin/env python
#
-*- coding:utf-8 -*-
__author__
=
'shouke'
#!/usr/bin/env
python
#
-*- coding:utf-8 -*-
import
threading
import
time
class
TestClass:
def
__init__(self,
num):
self.num
= num
global_var
=
0
def
testfn(num, obj):
global
global_var
global_var
= num
local_var
= num *
2
obj.num
= num *
2
time.sleep(5)
print("thread
id:",
threading.get_ident(),
'num:',
num,
'obj.num:',
obj.num,
'local_var:',
local_var,
'global_var:',
global_var)
for
i
in
range(0,
5):
#
# 多线程执行性能监控
thread
= threading.Thread(target=testfn,
name="testfn"+str(i),
args=(i,
TestClass(i)))
thread.start()
结论:
1、如下,通过args给线程即将调用函数(为方便描述,暂且称它为 “线程函数”)传递参数,可以做到每个线程都使用各自的参数去调用线程函数。
thread = threading.Thread(target=testfn,
name="testfn"+str(i),
args=(i,
TestClass(i)))
2、如下,线程函数里的局部变量(例中除去global_var之外的变量),都存储在栈内存中,而每个线程都有自己的栈内存,彼此独立,所以,每个线程对局部变量的赋值,读取操作互不影响。也就是说,多线程并发的情况下,局部变量是“安全”的,而全局变量存储在堆内存中,堆内存为所有线程共享,对所有线程都是可见的,所以两个以上的线程访问全局变量时,就会出现所谓的“不安全”,如下,第一个线程访问了全局变量 global_var,赋值为对应的num,然后中间sleep了5秒,在此期间,另一个线程访问了全局变量,赋值为另一个num,然后第一个线程醒来了,发现全局变量 global_var 已经不是它要的值了。
def
testfn(num, obj):
global
global_var
global_var
= num
local_var
= num *
2
obj.num
= num *
2
time.sleep(5)
2.代码实践2
#!/usr/bin/env python
#
-*- coding:utf-8 -*-
import
threading
import
time
thread_local_obj
= threading.local()
class
TestClass:
def
__init__(self,
num):
self.num
= num
global_var
=
0
def
testfn(num, obj):
global
global_var
global_var
= num
local_var
= num *
2
obj.num
= num *
2
thread_local_obj.obj
= obj
time.sleep(5)
other_task()
print("thread
id:",
threading.get_ident(),
'num:',
num,
'obj.num:',
obj.num,
'local_var:',
local_var,
'global_var:',
global_var)
def
other_task():
print("thread
id:",
threading.get_ident(),
'obj.num:',
thread_local_obj.obj.num ,
threading.currentThread().name)
for
i
in
range(0,
5):
#
# 多线程执行性能监控
thread
= threading.Thread(target=testfn,
name="testfn"+str(i),
args=(i,
TestClass(i)))
thread.start()
如上,线程函数中调用了另一个函数,我们希望在这个函数中做些操作,比如读取和线程关联的对象的属性值、修改属性值,这个按常规思维也可以通过传递函数参数来实现, 如下
other_task(obj):
print(obj.num)
问题是,线程函数里可能会调用多个函数,被调用的每个函数也可能会调用多个函数,所有这些函数都可能用到线程关联的对像,这样的话,需要逐层传递参数,很麻烦
解决方案:
创建全局对象,如下
thread_local_obj = threading.local()
然后在 线程函数
里通过
thread_local_obj.attr
= xxx 的方式,绑定线程关联的东西,其它地方使用时,会自动匹配与线程关联的值
作者:授客
微信/QQ:1033553122
全国软件测试QQ交流群:7156436
Git地址:https://gitee.com/ishouke
友情提示:限于时间仓促,文中可能存在错误,欢迎指正、评论!
作者五行缺钱,如果觉得文章对您有帮助,请扫描下边的二维码打赏作者,金额随意,您的支持将是我继续创作的源动力,打赏后如有任何疑问,请联系我!!!
微信打赏
支付宝打赏 全国软件测试交流QQ群