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 的方式,绑定线程关联的东西,其它地方使用时,会自动匹配与线程关联的值
Python_关于多线程下变量赋值取值的一点研究的更多相关文章
- 【学习笔记】Shell-1 变量:命名规范、变量赋值/取值/取消、局部变量/全局变量、预设环境变量
1.Shell变量 从变量的实质上来说,变量名是指向一片用于存储数据的内存空间. Shell变量是一种弱类型的变量,即声明变量时不需要指定其变量类型,也不需求遵循“先声明再使用”的规定,想用即可用. ...
- TextBox只读时不能通过后台赋值取值解决办法
给页面的TextBox设置ReadOnly="True"时,在后台代码中不能赋值取值,下边几种方法可以避免: 1.不设置ReadOnly,设置onfocus=this.blur( ...
- C# 基础控制台程序的创建,输出,输入,定义变量,变量赋值,值覆盖,值拼接,值打印
基础学习内容有 Console.WriteLine("要输出的内容");//往外输出内容的 Console.ReadLine(); //等待用户输入,按回车键结束,防止程序闪退 控 ...
- Java循环一个对象的所有属性,并通过反射给这些属性赋值/取值
Java循环一个对象的所有属性,并通过反射给这些属性赋值/取值 说到循环遍历,最常见的遍历数组/列表.Map等.但是,在开发过程中,有时需要循环遍历一个对象的所有属性.遍历对象的属性该如何遍历呢?查了 ...
- python练习题,写一个方法 传进去列表和预期的value 求出所有变量得取值可能性(例如list为[1,2,3,4,5,6,12,19],value为20,结果是19+1==20只有一种可能性),要求时间复杂度为O(n)
题目:(来自光荣之路老师)a+b==valuea+b+c=valuea+b+c+d==valuea+b+c+d+...=valuea和b....取值范围都在0-value写一个方法 传进去列表和预期得 ...
- ASP.Net TextBox只读时不能通过后台赋值取值
给页面的TextBox设置ReadOnly="True"时,在后台代码中不能赋值取值,下边几种方法可以避免: 1.不设置ReadOnly,设置onfocus=this.blur() ...
- switch条件变量的取值类型
switch条件变量的取值类型主要有以下六种: 1)JDK1.5(不含JDK1.5)之前只能是byte.short.int.char类型,不能是float.double.long.boolean类型. ...
- C#多线程交替赋值取值
static AutoResetEvent auto=new AutoResetEvent(false); ; ; static void Main() { Thread th1 = new Thre ...
- Loadrunner 关于参数赋值取值的操作
1.参数的赋值和取值 lr_save_string("hello world","param"); lr_eval_string("{param}&q ...
随机推荐
- deepin卸载mysql并安装设置mysql5.7
mysql完全卸载以及安全安装 完全卸载 sudo apt purge mysql-* sudo rm -rf /etc/mysql/ /var/lib/mysql sudo apt autoremo ...
- (转)asyncio --- 异步 I/O
原文:https://docs.python.org/zh-cn/3/library/asyncio.html asyncio 是用来编写 并发 代码的库,使用 async/await 语法. asy ...
- Centos6.5搭建grok匹配测试网站
最近在使用ELK对日志进行集中管理,因为涉及到日志的规则经常要用到http://grokdebug.herokuapp.com/进行调试,但是国外的网站访问太慢,这儿推荐一个国内的网站http://g ...
- Linux编程 24 shell编程(结构化 if [ condition ] 数值比较,字符串比较)
一.概述 接着上篇讲的结构化命令,最后讲到了test命令的另一种写法 if [ condition ],它的语法格式如下: --格式如下: if [ condition ] then commands ...
- Android--UI之ScrollView
前言 本篇博客主要讲解ScrollView和HorizontalScrollView两个容器的使用.它们分别代表了垂直滚动以及水平滚动,滚动的内容是它其中包含的View.在本篇会简单介绍ScrollV ...
- 1197多行事务要求更大的max_binlog_cache_size处理与优化
1197多语句事务要求更大的max_binlog_cache_size报错 binlog_cache_size:为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存,提高记录bi ...
- Leetcode 1-10
这篇文章介绍Leetcode1到10题的解决思路和相关代码. 1. Two sum 问题描述:给定一个整数数组,返回两个数字的索引,使它们加起来等于一个特定的目标. 例子: Given nums = ...
- SpringMVC学习(二)———— 参数绑定
一.参数绑定 1.1.什么是参数绑定? 客户在浏览器端会提交一些参数到服务器端,比如用户的登录等,就会传username 和 password过来,springmvc则通过参数绑定组件将请求参数的内容 ...
- Perl数据序列化和持久化(入门):Storable模块
Perl提供了一个Storable模块,用来对数据结构进行序列化(serialization,Perl中称为冻结),也就是将数据结构保存为二进制数据. 序列化后的数据可以写入文件实现持久化,可以将持久 ...
- 入侵感知系列之webshell检测思路
Webshell检测 背景: 在B/S架构为主流的当下,web安全成了攻防领域的主战场,其中上传webshell是所有web黑客入侵后一定会做的事,所以检测网站中是否有webshell程序是判断被 ...