当前位置:  开发笔记 > 编程语言 > 正文

什么是Python中的"线程本地存储",为什么需要它?

如何解决《什么是Python中的"线程本地存储",为什么需要它?》经验,为你挑选了3个好方法。

特别是在Python中,如何在线程之间共享变量?

虽然我之前使用threading.Thread过,但我从未真正理解或看到变量如何共享的例子.它们是在主线和孩子之间共享还是仅在孩子之间共享?我什么时候需要使用线程本地存储来避免这种共享?

我已经看到很多关于通过使用锁来同步线程间共享数据访问的警告,但我还没有看到问题的一个很好的例子.

提前致谢!



1> Thomas Woute..:

在Python中,除了函数局部变量之外,所有内容都是共享的(因为每个函数调用都有自己的局部集合,线程总是单独的函数调用.)即便如此,只有变量本身(引用对象的名称)是功能的本地; 对象本身总是全局的,任何东西都可以引用它们.Thread在这方面,特定线程的对象不是特殊对象.如果将Thread对象存储在所有线程都可以访问的地方(如全局变量),则所有线程都可以访问该Thread对象.如果你想原子地修改任何东西你不只是在这个相同的线程中创建,并且没有存储其他线程可以获得的任何地方,你必须通过锁来保护它.并且所有线程当然必须共享这个锁,否则它不会非常有效.

如果你想要实际的线程局部存储,那就是它的位置threading.local.threading.local线程之间不共享属性; 每个线程只看到它自己放在那里的属性.如果您对它的实现感到好奇,那么源代码在标准库中的_threading_local.py中.



2> 小智..:

请考虑以下代码:

#/usr/bin/env python

from time import sleep
from random import random
from threading import Thread, local

data = local()

def bar():
    print("I'm called from", data.v)

def foo():
    bar()

class T(Thread):
    def run(self):
        sleep(random())
        data.v = self.getName()   # Thread-1 and Thread-2 accordingly
        sleep(1)
        foo()
 >> T().start(); T().start()
I'm called from Thread-2
I'm called from Thread-1 

这里使用threading.local()作为一种快速而肮脏的方式将一些数据从run()传递到bar()而不改变foo()的接口.

请注意,使用全局变量不会起作用:

#/usr/bin/env python

from time import sleep
from random import random
from threading import Thread

def bar():
    global v
    print("I'm called from", v)

def foo():
    bar()

class T(Thread):
    def run(self):
        global v
        sleep(random())
        v = self.getName()   # Thread-1 and Thread-2 accordingly
        sleep(1)
        foo()
 >> T().start(); T().start()
I'm called from Thread-2
I'm called from Thread-2 

同时,如果你能负担得起将这些数据作为foo()的参数传递 - 它将是一种更优雅,设计更好的方式:

from threading import Thread

def bar(v):
    print("I'm called from", v)

def foo(v):
    bar(v)

class T(Thread):
    def run(self):
        foo(self.getName())

但是,当使用第三方或设计不良的代码时,这并不总是可行的.



3> Aaron Maenpa..:

您可以使用创建线程本地存储threading.local().

>>> tls = threading.local()
>>> tls.x = 4 
>>> tls.x
4

存储到tls的数据对于每个线程都是唯一的,这将有助于确保不会发生无意的共享.

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有