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

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

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

 

1.代码实践1

#!/usr/bin/env python
# -*- coding:utf-8 -*-

__author__ ='shouke'

#!/usr/bin/env python
# -*- coding:utf-8 -*-

importthreading
importtime

classTestClass:
   def__init__(self, num):
       self.num = num

global_var =0
deftestfn(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)

foriinrange(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,然后中间sleep5秒,在此期间,另一个线程访问了全局变量,赋值为另一个num,然后第一个线程醒来了,发现全局变量 global_var 已经不是它要的值了。

deftestfn(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 -*-

importthreading
importtime


thread_local_obj = threading.local()

classTestClass:
   def__init__(self, num):
       self.num = num

global_var =0
deftestfn(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)

defother_task():
   print("thread id:", threading.get_ident(),'obj.num:', thread_local_obj.obj.num , threading.currentThread().name)


foriinrange(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 的方式,绑定线程关联的东西,其它地方使用时,会自动匹配与线程关联的值

目录
相关文章
|
13天前
|
Python
python增量赋值运算的应用
Python中的增量赋值运算符用于便捷地执行算术操作,如`+=`, `-=`等,它们分别代表加法、减法、乘法、除法、取模、整除和幂运算。
13 1
|
14天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
24天前
|
算法 数据处理 Python
Python并发编程:解密异步IO与多线程
本文将深入探讨Python中的并发编程技术,重点介绍异步IO和多线程两种常见的并发模型。通过对比它们的特点、适用场景和实现方式,帮助读者更好地理解并发编程的核心概念,并掌握在不同场景下选择合适的并发模型的方法。
|
1月前
|
安全 Python
Python中的并发编程:多线程与多进程技术探究
本文将深入探讨Python中的并发编程技术,重点介绍多线程和多进程两种并发处理方式的原理、应用场景及优缺点,并结合实例分析如何在Python中实现并发编程,以提高程序的性能和效率。
|
1天前
|
Java 数据库连接 数据处理
Python从入门到精通:3.1.2多线程与多进程编程
Python从入门到精通:3.1.2多线程与多进程编程
|
2天前
|
存储 Python
Python变量类型
Python变量类型
8 0
|
2天前
|
存储 Python
Python的变量与数据类型详解
Python的变量与数据类型详解
11 0
|
7天前
|
索引 Python
Python高维变量选择:SCAD平滑剪切绝对偏差惩罚、Lasso惩罚函数比较
Python高维变量选择:SCAD平滑剪切绝对偏差惩罚、Lasso惩罚函数比较
|
8天前
|
调度 Python
Python多线程、多进程与协程面试题解析
【4月更文挑战第14天】Python并发编程涉及多线程、多进程和协程。面试中,对这些概念的理解和应用是评估候选人的重要标准。本文介绍了它们的基础知识、常见问题和应对策略。多线程在同一进程中并发执行,多进程通过进程间通信实现并发,协程则使用`asyncio`进行轻量级线程控制。面试常遇到的问题包括并发并行混淆、GIL影响多线程性能、进程间通信不当和协程异步IO理解不清。要掌握并发模型,需明确其适用场景,理解GIL、进程间通信和协程调度机制。
28 0
|
8天前
|
开发者 索引 Python
Python中的海象运算符:简洁而强大的赋值表达式
【4月更文挑战第17天】Python 3.8 引入了海象运算符 `:=`,也称赋值表达式运算符,用于在表达式内部赋值,简化代码并提升可读性。它能用于条件判断、循环控制和函数参数等场景,优化逻辑流程。然而,使用时需注意可读性、运算符优先级及赋值限制,以确保代码清晰易懂。海象运算符是Python编程的一个有用工具,但应根据情况谨慎使用。

热门文章

最新文章