gpt4 book ai didi

Python:在另一个线程修改字典时迭代字典

转载 作者:太空宇宙 更新时间:2023-11-03 14:33:12 32 4
gpt4 key购买 nike

我有一个具有“观察者”属性的 pyglet 窗口。观察者有一本字典“dict”。在main_loop()函数中窗口根据observer.dict的内容重新绘制窗口。观察者本身是一个读取流的线程,将读数添加到字典中。观察者还有一个计时器线程,每秒检查字典中是否有过时的项目,如果有,则删除它们。

显然,如果在窗口遍历 dict 时添加或删除项目,这可能会导致问题。我目前的解决方法是每次都对字典进行深度复制,然后绘制副本。这似乎可行,但这是一个丑陋的解决方案。

我对 python 很陌生,尤其是 w.r.t 线程/锁定等。我想我需要观察者在添加或删除项目时“锁定”字典。有人可以给我一些提示,先看哪里吗?

我试图从我的代码中提取有意义的结构,但都太长了。我希望你能明白主要思想。

class GraphConsole(window.Window):
def __init__(self, *args, **kwargs):
window.Window.__init__(self, *args, **kwargs)

def init(self, observer):
self.observer = observer


def main_loop(self):
while not self.has_exit:
...
self.draw()

def draw(self):
dict_copy = deepcopy(self.observer.dict) # <-- UGLY WORKAROUND
for k, v in dict_copy.iteritems():
...


class Observer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.dict = {}
self.timer = Timer(1, self.delete_obsolete);
self.timer.start()

def run(self):
while True:
...
# read a stream
self.dict.append(<new_element>)
...


def delete_obsolete(self):
...
del self.dict[...]
...



class Timer(threading.Thread):
def __init__(self, interval_in_seconds, func):
threading.Thread.__init__(self)
self.interval_in_seconds = interval_in_seconds
self.func = func

def run(self):
while True:
self.func();
time.sleep(self.interval_in_seconds)



if __name__ == "__main__":

observer = Observer();
observer.start()

graph_console = GraphConsole()
graph_console.init(observer)
graph_console.main_loop()

最佳答案

可能一些简单的锁可以解决您的问题。观察者类:

class Observer(threading.Thread):
def __init__(self, lock):
threading.Thread.__init__(self)
self.dict_lock = lockthreading.RLock()
self.dict = {}
self.timer = Timer(1, self.delete_obsolete);
self.timer.start()

def run(self):
while True:
...
with self._dict_lock:
# read a stream
self.dict.append(<new_element>)
...


def delete_obsolete(self):
...
with self._dict_lock:
del self.dict[...]
...

图形控制台类:

class GraphConsole(window.Window):
def __init__(self, *args, **kwargs):
window.Window.__init__(self, *args, **kwargs)

def init(self, observer):
self.observer = observer

def main_loop(self):
while not self.has_exit:
...
self.draw()

def draw(self):
with self.observer.dict_lock:
for k, v in dict_copy.iteritems():
...

我最初的回答有点不完整,但我知道你明白了:)

关于Python:在另一个线程修改字典时迭代字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6968856/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com