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 = queuedef run(self):while True:data = self.queue.get()#print dataRegDevID = data#print datasend_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 requestdef __init__(self, queue):threading.Thread.__init__(self)self.queue = queuedef run(self):while True:data = self.queue.get()#print datadata = RegDevID#print datasend_queue.put(data)self.queue.task_done()
# ShareVar.py
RegDevID = '100'
That's it, when thread a changed the RegDevID, thread b still get it's default value.
Thanks advanced.
from ShareVar import RegDevIDclass Test():def __init__(self):passdef SetVar(self):RegDevID = 999def GetVar(self):print RegDevIDif __name__ == '__main__':test = Test();test.SetVar()test.GetVar()
The ShareVar.py:
RegDevID = 100
The result:
100
why?
My guess is you are trying to access the shared variable without a lock
. If you do not acquire a lock and attempt to read a shared variable in one thread, while another thread is writing to it, the value could be indeterminate.
To remedy, make sure you acquire a lock in the thread before reading or writing to it.
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
Read about Python threading.
Answer to your bottom problem with scoping:
In your bottom sample, you are experiencing a problem with scoping. In SetVar()
, you are create a label RegDevID
local to the function. In GetVar()
, you are attempting to read from a label RegDevID
but it is not defined. So, it looks higher in scope and finds one defined in the import. The variables need to be in the same scope if you hope to have them reference the same data.
Although scopes are determined statically, they are used dynamically.At any time during execution, thereare at least three nested scopes whosenamespaces are directly accessible:
the innermost scope, which is searched first, contains the local namesthe scopes of any enclosing functions, which are searched startingwith the nearest enclosing scope,contains non-local, but alsonon-global namesthe next-to-last scope contains the current module’s global namesthe outermost scope (searched last) is the namespace containingbuilt-in names
If a name is declared global, then allreferences and assignments go directlyto the middle scope containing themodule’s global names. Otherwise, allvariables found outside of theinnermost scope are read-only (anattempt to write to such a variablewill simply create a new localvariable in the innermost scope,leaving the identically named outervariable unchanged).
Read about scoping.