带有全局变量的python线程
我在编写python线程代码时遇到了一个问题,我编写了一些workers线程类,它们都导入了一个全局文件,比如sharvar.py,我需要一个变量,比如regdevid来保持 跟踪寄存器设备id,然后当一个线程更改其值时,其他线程可以 获取新的值,但结果是:当一个线程更改其值时,其他线程仍然获得我在sharevar.py文件中定义的默认值,为什么? 我有什么问题吗带有全局变量的python线程,python,multithreading,variables,global,Python,Multithreading,Variables,Global,我在编写python线程代码时遇到了一个问题,我编写了一些workers线程类,它们都导入了一个全局文件,比如sharvar.py,我需要一个变量,比如regdevid来保持 跟踪寄存器设备id,然后当一个线程更改其值时,其他线程可以 获取新的值,但结果是:当一个线程更改其值时,其他线程仍然获得我在sharevar.py文件中定义的默认值,为什么? 我有什么问题吗 # thread a from UserShare import RegDevID import threading class A
# thread a
from UserShare import RegDevID
import threading
class AddPosClass(threading.Thread):
global commands
# We need a pubic sock, list to store the request
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while True:
data = self.queue.get()
#print data
RegDevID = data
#print data
send_queue.put(data)
self.queue.task_done()
# thread b
import threading
from ShareVar import send_queue, RegDevID
"""
AddPos -- add pos info on the tail of the reply
"""
class GetPosClass(threading.Thread):
global commands
# We need a pubic sock, list to store the request
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while True:
data = self.queue.get()
#print data
data = RegDevID
#print data
send_queue.put(data)
self.queue.task_done()
# ShareVar.py
RegDevID = '100'
就是这样,当线程a更改RegDevID时,线程b仍然得到它的默认值。
谢谢
from ShareVar import RegDevID
class Test():
def __init__(self):
pass
def SetVar(self):
RegDevID = 999
def GetVar(self):
print RegDevID
if __name__ == '__main__':
test = Test();
test.SetVar()
test.GetVar()
ShareVar.py文件:
RegDevID = 100
结果是:
100
为什么?我猜您试图在没有
锁的情况下访问共享变量。如果未获取锁并尝试读取一个线程中的共享变量,而另一个线程正在写入该变量,则该值可能不确定
要进行补救,请确保在读取或写入线程之前在线程中获得锁
import threading
# shared lock: define outside threading class
lock = threading.RLock()
# inside threading classes...
# write with lock
with lock: #(python 2.5+)
shared_var += 1
# or read with lock
with lock:
print shared_var
了解
关于范围界定的基本问题的答案:
在下面的示例中,您遇到了范围界定问题。在SetVar()
中,您将创建函数本地的标签RegDevID
。在GetVar()
中,您试图从标签RegDevID
中读取数据,但该标签未定义。因此,它在范围上看起来更高,并找到在导入中定义的范围。如果希望这些变量引用相同的数据,那么它们需要在相同的范围内
虽然范围是静态确定的,但它们是动态使用的。
在执行过程中的任何时候
至少有三个嵌套作用域
名称空间可以直接访问:
最里面的范围(首先搜索)包含本地名称
开始搜索的任何封闭函数的作用域
具有最近的封闭范围,
包含非本地,但也包含
非全局名称
倒数第二个作用域包含当前模块的全局名称
最外层的作用域(最后搜索)是包含
内置名称
如果名称声明为全局,则所有
参考资料和作业直接进行
到包含
模块的全局名称。否则,所有
在外部找到的变量
最里面的作用域是只读的(一个
试图写入这样一个变量
只会创建一个新的本地
最内层范围中的变量,
离开同名的外部
变量(未更改)
.您确定您发布了实际代码吗?您从两个不同的模块导入了RegDevID:
# thread a
from UserShare import RegDevID
vs
不管怎样,您的问题与线程无关。将“fromsomemoduleimportsomevar”视为赋值语句。如果模块尚未加载,则大致相当于加载模块的魔法,然后是:
somevar = sys.modules['somemodule'].somevar
从其他模块导入RegDevID时,您正在当前模块中创建一个新名称。如果您更改了对象,那么对象的其他用户将看到更改,但是如果您在此模块中重新绑定名称,那么这只会影响本地名称,而不会更改原始模块中的任何内容
相反,您需要在另一个模块中重新绑定变量:
import ShareVar
...
ShareVar.RegDevID = data
当然,如果你创建一个类来管理你的共享状态,你会发现你会做得更好
第二段代码是局部和全局变量:
def SetVar(self):
RegDevID = 999
在函数内部,您创建了一个新的局部变量RegDevID,它与同名的全局变量无关。如果要重新绑定全局变量,请使用global
语句:
def SetVar(self):
global RegDevID
RegDevID = 999
你可能没有什么问题,但也许你应该展示你的代码。请正确格式化你的代码…非常感谢,但我如何解决这个问题,我想让我的代码干净,每个文件一个线程类,但他们确实需要共享一些变量,这些变量应该是可写的,所以有什么方法可以实现吗?
def SetVar(self):
global RegDevID
RegDevID = 999