带有全局变量的python线程 [英] python threading with global variables

查看:136
本文介绍了带有全局变量的python线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编写python线程代码时遇到问题,我写了一些worker线程类,它们都导入了一个全局文件(如sharevar.py),我需要像regdevid这样的变量来保持 跟踪寄存器设备ID,然后当一个线程更改其值时,其他线程可以 重新获得它,但是结果是:当一个线程更改它的值时,其他线程仍然获得我在sharevar.py文件中定义的默认值,为什么呢? 我有什么问题吗?

i encountered a problem when write python threading code, that i wrote some workers threading classes, they all import a global file like sharevar.py, i need a variable like regdevid to keep tracking the register device id, then when one thread change it's value, then other threads can get it fresh, but the result is that: when one thread change it's value, the others still get the default value i defined in sharevar.py file, why? anything wrong with me?

# 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仍获得其默认值. 谢谢,谢谢.

That's it, when thread a changed the RegDevID, thread b still get it's default value. Thanks advanced.

    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:

The ShareVar.py:

RegDevID = 100

结果:

100

为什么?

推荐答案

确定要发布您的实际代码吗?您从两个不同的模块导入了RegDevID:

Are you sure you posted your actual code? You imported RegDevID from two different modules:

# thread a
from UserShare import RegDevID

vs

# thread b
from ShareVar import send_queue, RegDevID 

无论哪种方式,您的问题都与线程无关.可以将从somemodule导入somevar"作为赋值语句.如果尚未加载模块,则大致等同于加载模块的魔术,然后执行以下操作:

Either way, your problam has nothing to do with threading. Think of 'from somemodule import somevar' as an assignment statement. Roughly equivalent to some magic to load the module if it isn't already loaded followed by:

somevar = sys.modules['somemodule'].somevar

从另一个模块导入RegDevID时,您正在当前模块中创建一个新名称.如果您对该对象进行了突变,则该对象的其他用户将看到更改,但是,如果您在此模块中重新绑定了名称,则只会影响本地名称,而不会更改原始模块中的任何内容.

When you import RegDevID from the other module you are creating a fresh name in the current module. If you mutate the object then other users of the object will see the changes, but if you rebind the name in this module then that only affects the local name it doesn't change anything in the original module.

相反,您需要在另一个模块中重新绑定变量:

Instead you need to rebind the variable in another module:

import ShareVar
...
ShareVar.RegDevID = data

当然,如果您创建一个类来管理共享状态,您会发现自己进步很多.

Except of course you'll find you get on much better if you create a class to manage your shared state.

您的第二段代码只是误解了局部变量和全局变量:

Your second bit of code is ejust misunderstanding local and global variables:

def SetVar(self):
    RegDevID = 999

在函数内部创建了一个新的局部变量RegDevID,它与同名的全局变量无关.如果要重新绑定全局变量,请使用global语句:

inside the function you created a new local variable RegDevID which is nothing to do with the global variable of the same name. Use the global statement if you want to rebind a global variable:

def SetVar(self):
    global RegDevID
    RegDevID = 999

这篇关于带有全局变量的python线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆