はじめに
短い: Python で Gtk/Gstreamer アプリケーションを (メモリ) サンドボックス化し、定期的に再起動する必要があります。
Long : カメラからデータを取得するより大きなコードのチャンクに使用するライブラリ (gstreamer) でメモリ リークが発生しています。それについての議論を避けるために、私はしばらくの間その問題を解決しようとしましたが、できませんでした. カメラのデータが必要なので、メモリがいっぱいになる前に定期的に行ってソフトウェアを再起動する手動ハックの自動化であるはずのソリューションをハックすることにしました。
しかし、私は Gtk にまったく慣れておらず、Python のメモリ管理についてほとんど知識がありません。したがって、私は問題に遭遇します。
設定
そのため、プログラムは Gtk3 を使用して Python で記述されています。私myPythonObjectWithGtkStuff
は本質的にhttp://bazaar.launchpad.net/~jdose/+junk/gst-examples/view/head:/webcam-1.0のよりファンシーなバージョンです。しかし、特に と の Gtk の部分__init__()
はrun()
同じです。(この行http://bazaar.launchpad.net/~jdose/+junk/gst-examples/view/head:/webcam-1.0#L51と関数に注意してください。これon_sync_message()
はニシンかもしれませんが、 xid ハンドルを使用して gstreamer ストリームを Gtk 描画領域に向ける処理を行う)
問題/解決策 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()
ここでの問題は、最初は完全に正常に開始されることですが、最初のプロセスが戻り、ループが 2 番目のプロセスを起動すると、 of を呼び出した瞬間に次のエラーが発生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.
何をすべきか?
私が今必要としているのは、2 つの問題のいずれかに対する解決策です。最初の解決策でオブジェクトがメモリから完全に削除されるようにするにはどうすればよいですか、または解決策 2 でその X サーバー エラーを回避するにはどうすればよいでしょうか。
self.window.destroy()
my を呼び出すだけでは、obj
すべての Gtk を殺すには不十分なのかもしれません。それは Gtk アプリケーションを閉じる正しい方法ですか?