Python_关于多线程下变量赋值取值的一点研究

时间:2022-12-21 10:53:30

关于多线程下变量赋值取值的一点研究

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()


 

Python_关于多线程下变量赋值取值的一点研究Python_关于多线程下变量赋值取值的一点研究

结论:

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()

Python_关于多线程下变量赋值取值的一点研究Python_关于多线程下变量赋值取值的一点研究

如上,线程函数中调用了另一个函数,我们希望在这个函数中做些操作,比如读取和线程关联的对象的属性值、修改属性值,这个按常规思维也可以通过传递函数参数来实现,  如下

other_task(obj):

print(obj.num)

问题是,线程函数里可能会调用多个函数,被调用的每个函数也可能会调用多个函数,所有这些函数都可能用到线程关联的对像,这样的话,需要逐层传递参数,很麻烦

解决方案:

创建全局对象,如下


thread_local_obj = threading.local()


然后在
 线程函数
里通过

thread_local_obj
.attr
= xxx 的方式,绑定线程关联的东西,其它地方使用时,会自动匹配与线程关联的值

Python_关于多线程下变量赋值取值的一点研究的更多相关文章

  1. 【学习笔记】Shell-1 变量:命名规范、变量赋值/取值/取消、局部变量/全局变量、预设环境变量

    1.Shell变量 从变量的实质上来说,变量名是指向一片用于存储数据的内存空间. Shell变量是一种弱类型的变量,即声明变量时不需要指定其变量类型,也不需求遵循“先声明再使用”的规定,想用即可用. ...

  2. TextBox只读时不能通过后台赋值取值解决办法

    给页面的TextBox设置ReadOnly="True"时,在后台代码中不能赋值取值,下边几种方法可以避免:  1.不设置ReadOnly,设置onfocus=this.blur( ...

  3. C# 基础控制台程序的创建,输出,输入,定义变量,变量赋值,值覆盖,值拼接,值打印

    基础学习内容有 Console.WriteLine("要输出的内容");//往外输出内容的 Console.ReadLine(); //等待用户输入,按回车键结束,防止程序闪退 控 ...

  4. Java循环一个对象的所有属性,并通过反射给这些属性赋值/取值

    Java循环一个对象的所有属性,并通过反射给这些属性赋值/取值 说到循环遍历,最常见的遍历数组/列表.Map等.但是,在开发过程中,有时需要循环遍历一个对象的所有属性.遍历对象的属性该如何遍历呢?查了 ...

  5. 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写一个方法 传进去列表和预期得 ...

  6. ASP.Net TextBox只读时不能通过后台赋值取值

    给页面的TextBox设置ReadOnly="True"时,在后台代码中不能赋值取值,下边几种方法可以避免: 1.不设置ReadOnly,设置onfocus=this.blur() ...

  7. switch条件变量的取值类型

    switch条件变量的取值类型主要有以下六种: 1)JDK1.5(不含JDK1.5)之前只能是byte.short.int.char类型,不能是float.double.long.boolean类型. ...

  8. C#多线程交替赋值取值

    static AutoResetEvent auto=new AutoResetEvent(false); ; ; static void Main() { Thread th1 = new Thre ...

  9. Loadrunner 关于参数赋值取值的操作

    1.参数的赋值和取值 lr_save_string("hello world","param"); lr_eval_string("{param}&q ...

随机推荐

  1. React Native 之生命周期

    前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...

  2. 深度学习笔记------linux下配置安装caffe-cpu only模式

    本文适合初学者学习配置caffe的最简单方法.这是我在看了网上各种大神的方法后总结的最傻瓜式的配置方法了. 本人也是在不断地配置caffe过程中受打击与成长@.@ 第一步.配置caffe所需的依赖环境 ...

  3. C#托管代码与C++非托管代码互相调用

    http://www.cnblogs.com/Jianchidaodi/archive/2009/03/11/1407270.html#1473515 http://www.cnblogs.com/J ...

  4. file_get_contents()的另一种使用方法

    今天在网上看到一篇挺不错的文章,拿过来保存学习一下.本文源地址为:http://www.kuitao8.com/20140727/2867.shtml $data = file_get_content ...

  5. Aspose.cells异步读写操作

    public class AsyncExcel : Excel { static readonly object _objForlock = new object(); //public List&l ...

  6. java中从含反斜杠路径截取文件名的方法

    例如:获取到的文件路径为C:\Documents and Settings\Leeo\My Documents\logo.gif现在想要取得图片的名称logo.gif,我们知道反斜杠“\”是转义字符, ...

  7. [Swift]LeetCode108. 将有序数组转换为二叉搜索树 | Convert Sorted Array to Binary Search Tree

    Given an array where elements are sorted in ascending order, convert it to a height balanced BST. Fo ...

  8. SQL Server中使用数据库快照的方式来完成测试环境中数据库的轻量级备份还原操作

    在开发或者测试环境的数据库中,经常会发现有开发或者测试人员误删除表或者数据的情况,对于开发或者测试库,一般都没有安排定时的备份任务去备份数据库,一方面是由于存储资源有限,不太可能给开发或者测试环境准备 ...

  9. ms sqlserver2008r2 自动备份

    日常工作中利用SQL SQLSERVER 2008 的维护计划对数据库进行定期的备份,这样一方面可以对数据库进行备份保证数据安全另一方面也可以减轻对维护人员的负担. 一般对于WEB 服务器进 行维护都 ...

  10. Linux下搭建LAMP环境(YUM)

    安装Apache 1.安装Apache yum -y install httpd 2. Apache配置httpd.conf 通过命令 find / -name httpd.conf 找到Apache ...