liu*_*unx -1 python variables multithreading global
我在编写python线程代码时遇到了一个问题,我编写了一些工作线程类,它们都导入了一个像sharevar.py这样的全局文件,我需要一个像regdevid这样的变量来跟踪寄存器设备id,然后当一个线程更改它的值时,然后其他线程可以让它变得新鲜,但结果是:当一个线程更改它的值时,其他线程仍然获得我在sharevar.py文件中定义的默认值,为什么?我有什么不对吗?
# 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'
Run Code Online (Sandbox Code Playgroud)
就是这样,当线程更改了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()
Run Code Online (Sandbox Code Playgroud)
ShareVar.py:
RegDevID = 100
Run Code Online (Sandbox Code Playgroud)
结果:
100
Run Code Online (Sandbox Code Playgroud)
为什么?
我的猜测是你试图在没有a的情况下访问共享变量lock.如果您没有获取锁并尝试在一个线程中读取共享变量,而另一个线程正在写入它,则该值可能是不确定的.
要解决此问题,请确保在读取或写入线程之前获取线程中的锁定.
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
Run Code Online (Sandbox Code Playgroud)
阅读Python线程.
确定范围的底层问题:
在您的底部示例中,您遇到了范围问题.在SetVar(),您将创建RegDevID函数本地的标签.在GetVar(),您试图从标签读取RegDevID但它没有定义.因此,它在范围上看起来更高,并在导入中找到一个定义的.如果您希望变量引用相同的数据,则变量需要在同一范围内.
尽管范围是静态确定的,但它们是动态使用的.在执行期间的任何时候,至少有三个嵌套的作用域,其名称空间可以直接访问:
最先搜索的最内层作用域包含本地名称,从最近的封闭作用域开始搜索的任何封闭函数的作用域包含非本地名称,但也包含非全局名称,倒数第二个作用域包含当前模块的全局名称最外层作用域(最后搜索)是包含内置名称的名称空间
如果名称声明为全局,则所有引用和赋值将直接转到包含模块全局名称的中间作用域.否则,最里面的范围之外发现的所有变量都只读(尝试写这样的变量只会在最里面的范围内创建一个新的局部变量,离开同名外变量不变).
了解范围.
| 归档时间: |
|
| 查看次数: |
22297 次 |
| 最近记录: |