Python 线程中,变量的作用域会有什么不同

2024年7月24日服务端开发评论5,843字数 1504阅读5分0秒阅读模式

Python 线程中,变量的作用域会有什么不同

# 线程局部存储 thread_local_data = threading.local()

在Python中,线程中的变量作用域与普通的Python程序中的变量作用域是相似的,但在多线程环境中,需要注意线程间的数据共享和同步问题。以下是Python线程中变量的作用域概述:

  1. 全局作用域

    • 在模块级别定义的变量(即在所有函数和类之外定义的变量)在整个模块中都是可见的。
    • 在多线程环境中,全局变量可以被所有线程访问和修改。这意味着如果一个线程修改了全局变量的值,其他线程会看到这个变化。
  2. 局部作用域

    • 在函数或方法内部定义的变量是局部变量,只在该函数或方法内部可见。
    • 每个线程在执行函数时都有自己的局部变量副本,这些局部变量对其他线程不可见。
  3. 线程局部存储(Thread-Local Storage)

    • 有时需要确保每个线程有自己独立的一套变量,不与其他线程共享。可以使用threading.local()来创建线程局部存储。
    • 通过这种方式,在线程中存储的数据对其他线程是不可见的,确保线程安全。

示例代码

import threading

# 全局变量
global_var = 0

# 线程局部存储
thread_local_data = threading.local()

def thread_function(name):
    # 局部变量
    local_var = name
    # 线程局部变量
    thread_local_data.thread_var = name
    
    print(f"Thread {name}: global_var = {global_var}")
    print(f"Thread {name}: local_var = {local_var}")
    print(f"Thread {name}: thread_var = {thread_local_data.thread_var}")

# 创建多个线程
threads = []
for i in range(3):
    t = threading.Thread(target=thread_function, args=(i,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

# 修改全局变量
global_var = 10

# 再次创建多个线程
threads = []
for i in range(3):
    t = threading.Thread(target=thread_function, args=(i,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

输出结果

该示例展示了全局变量、局部变量和线程局部变量在多线程中的行为:

Thread 0: global_var = 0
Thread 0: local_var = 0
Thread 0: thread_var = 0
Thread 1: global_var = 0
Thread 1: local_var = 1
Thread 1: thread_var = 1
Thread 2: global_var = 0
Thread 2: local_var = 2
Thread 2: thread_var = 2

Thread 0: global_var = 10
Thread 0: local_var = 0
Thread 0: thread_var = 0
Thread 1: global_var = 10
Thread 1: local_var = 1
Thread 1: thread_var = 1
Thread 2: global_var = 10
Thread 2: local_var = 2
Thread 2: thread_var = 2

从输出可以看出:

  • 全局变量在所有线程中共享,修改后所有线程都能看到最新值。
  • 局部变量在每个线程中独立存在,互不影响。
  • 线程局部变量在每个线程中独立存在,互不影响。

记一次 Python 应用开发频繁假死的问题 服务端开发

记一次 Python 应用开发频繁假死的问题

问题背景 最近在开发一款自动化的应用,其中有一个自动化任务会由下面这三个按钮控制: 逻辑也很简单,我大概画下图就是这样的: 但是,在测试时,却发现了问题: 当我点击暂停任务后,此时子线程被阻塞。如果我...
记一次在 Python 中因为文件路径导致的错误 服务端开发

记一次在 Python 中因为文件路径导致的错误

最近在编写一个自动化应用,需要管理浏览器的状态。 通过单例模式的设计,实现了只有一个浏览器实例,这样其它模块或者函数调用这个浏览器类,用的都是同一个实例,就可以管理这个浏览器的状态了。 类似下面这样调...
Python 中单例模式的实现与使用 服务端开发

Python 中单例模式的实现与使用

实现方法 在Python中,单例模式可以通过多种方法实现。单例模式的目标是确保一个类只有一个实例,并提供一个全局访问点。以下是几种常见的实现单例模式的方法: 方法 1: 使用模块 Python中的模块...
实现基于权重的随机选择算法 学习笔记

实现基于权重的随机选择算法

今天我在做一款应用时,需要随机抽取问题,但是我不希望问题出现的概率是一样的,面对这种需求该如何解决呢? 于是我想到了在 Nginx 中,实现负载均衡时,可以给每个服务分别设置权重值,来实现自定义服务被...
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定