У меня есть окно pyglet, которое имеет атрибут «наблюдатель». У наблюдателя есть словарь «дикт». В функции main_loop () окно перерисовывает окно в соответствии с содержимым Observer.dict. Сам наблюдатель является потоком, читающим поток, добавляющим чтения к dict. Наблюдатель также имеет поток таймера, который каждую секунду проверяет наличие в dict устаревших элементов и, если это так, удаляет их.
Очевидно, что это может вызвать проблемы, если элементы добавляются или удаляются, пока окна перебирают dict. Мой текущий обходной путь - каждый раз делать глубокую копию указания и рисовать копию. Кажется, это работает, но это уродливое решение.
Я довольно новичок в python и, в частности, в w.r.t Threading / Locking / и т.д. Я думаю, мне нужен наблюдатель, чтобы "заблокировать" диктовку при добавлении или удалении элементов. Может кто-нибудь дать мне несколько советов, где искать в первую очередь?
Я пытался извлечь значимую структуру моего кода, все было бы слишком долго. Я надеюсь, что вы можете получить основную идею.
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()