我正在尝试创建一个全局状态变量,它是用回调方法(事件处理程序)编写的。 但是,回调在另一个内存位置创建一个副本(深层),其他方法(当然)没有看到它。 这是情况
class Server:
def __init__(self):
self.callbacks=[]
#create a web server instance to listen to requests
self.app=Flask("test")
def add_callback(self, func):
self.calbacks.append(func)
self.app.add_url_rule("/test", "test", self.handle_http_request)
def handle_http_request(self):
content = request.get_json(silent=True)
for ca in self.callbacks:
ca(content)
def start_server(self):
#some stuff starting flask here...
class SomeModule:
def __init__(self):
self.ws=Server()
self.ws.add_callback(self.callback)
self.callback_called=False
def callback(self, content):
print "callback executing---"
print "var addr before callback assign: "+str(hex(id(self.callback_called)))
self.callback_called=True
print "var addr after callback assign: "+str(hex(id(self.callback_called)))
def start(self):
self.ws.start()
#send a request to the server using the request library, which invokes all the trigger
#check the state variable:
print "var addr before check: "+str(hex(id(self.callback_called)))
if (not self.callback_called):
raise Exception("error...")
if __name__ == '__main__':
sm=SomeModule()
sm.start()
然后输出:
callback executing--- var addr before callback assign: 0x927910 var addr before callback assign: 0x927930 var addr before check: 0x927910
有谁能建议我如何避免这种情况? 在c ++中,它明确了如何访问指针和互斥锁。然而,在这里,我没有设法找到任何方法来对变量进行安全写入......
提前多多感谢!
答案 0 :(得分:1)
由于您在标签中使用多线程而不是多处理,我仍然会继续发布此答案。可能对某些人有帮助。
有些对象是immutable,正如你所说的那样被复制了。其他变量,例如dictionaries,往往不是可以从函数或威胁中操纵(不确定线程是否仅适用于某些情况)。
例如,如果将dict
作为参数传递给线程,则可以操纵该变量并影响变量的原始版本。
然而,这样做有风险。可能存在更新冲突,访问冲突,并且通常很难跟踪事情的发生。
但是这里有一个如何将dict
传递给线程并显示更改的示例。这很粗糙,但给你一个有效的例子。
from threading import *
class server(Thread):
def __init__(self, o):
self.o = o
Thread.__init__(self)
self.start()
def run(self):
for i in range(3):
self.o['test'] = i
test_var = {'test' : 0}
server(test_var)
while len(enumerate()) > 1: # Stupid and oversimplified wait for threads to end.
pass
print(test_var)
答案 1 :(得分:0)
问题实际上是在其他地方。 :(原因是,Flask(Web服务器)是在一个单独的线程中启动的,有些实例由于某种原因被复制。我没有进一步挖掘,只是避免使用Flask并切换到cherrypy并启动它在非阻塞模式。 Thinkgs开始按预期在那里工作。
@torxed,非常感谢你的帮助。它确实指出了我正确的方向!