вступление
Коротко: мне нужно (в памяти) помещать в песочницу приложение Gtk/Gstreamer в python и регулярно перезапускать его.
Долго: у меня возникла утечка памяти в библиотеке (gstreamer), которую я использую для большого фрагмента кода, который получает данные с камеры. Просто чтобы избежать споров по этому поводу, я пытался решить эту проблему с некоторого времени и не мог. Мне нужны данные камеры, поэтому я решил попробовать взломать решение, которое должно быть автоматизацией ручного взлома, который должен был бы выполняться регулярно и перезапускать программное обеспечение до того, как память заполнится.
Тем не менее, я совсем не привык к Gtk, и у меня очень мало знаний об управлении памятью Python. Поэтому я сталкиваюсь с проблемами.
Настраивать
Итак, теперь программа написана на питоне с использованием Gtk3. У меня есть myPythonObjectWithGtkStuff
, который по сути является более причудливой версией http://bazaar.launchpad.net/~jderose/+junk/gst-examples/view/head:/webcam-1.0 . Но особенно часть Gtk в __init__()
и run()
одинакова. (обратите внимание на эту строку http://bazaar.launchpad.net/~jderose/+junk/gst-examples/view/head:/webcam-1.0#L51, а также функцию on_sync_message()
, которая может быть отвлекающим маневром, но она связана с режиссурой поток gstreamer в область рисования Gtk с использованием дескриптора xid)
Проблема/Решение 1
Я представлял себе, как это работает, чтобы создать весь объект, содержащий весь код, в цикле while. Затем вызовите в какой-то момент времени window.destroy()
из основного цикла Gtk. Он вернется в цикл while, и будет создан еще один объект и т. д.
# shitty hack to restart the Gtk application once it got destroyed
while(1):
startVC(args)
с участием
def startVC(args):
mainloop = GObject.MainLoop()
obj = myPythonObjectWithGtkStuff(args)
obj.run()
del obj
Все идет нормально. Все работает, если сделать как написано выше. Проблема с этим решением заключается в том, что оно не освобождает память файла obj
. (Я думаю, что в основном остается утечка памяти, я не уверен).
редактировать:
В тот момент, когда я вызываю window.destroy(), окно Gtk закрывается, и я вижу, что использование памяти снижается до некоторого стабильного базового значения. Как только Gtk запускается снова, использование памяти возвращается к предыдущему использованию оперативной памяти плюс некоторая дополнительная память, соответствующая объему утечки памяти.
Проблема/решение 2
Теперь я подумал, что могу просто запустить Gtk в процессе и просто завершить его, когда он вернется, и запустить новый процесс.
while(1):
p = Process(target=startVC, args=(args,))
p.start()
p.join()
p.terminate()
Проблема здесь в том, что он запускается в первый раз отлично, но как только первый процесс возвращается и цикл запускает второй процесс, я получаю следующую ошибку в тот момент, когда я вызываю self.window = Gtk.Window()
в __init()__()
из myPythonObjectWithGtkStuff
:
Gdk-WARNING **: captureVideo.py: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.
который немного чередуется с
Gdk-WARNING **: captureVideo.py: Fatal IO error 0 (Success) on X server :0.
Что делать?
Сейчас мне нужно решение любой из двух проблем. Как я могу гарантировать, что объект будет полностью удален из памяти для первого решения, или как избежать этой ошибки X-сервера для решения 2.
Возможно, вызова self.window.destroy()
из моего obj
недостаточно, чтобы убить все вещи Gtk. Это правильный способ закрыть приложение Gtk?