あなたが示した場所でコードがクラッシュした場合、display.sendstop()
は呼び出されません。
Display
をcontext managerとして使用するのが最も望ましいと思うのですが、try/catchですべてのコードをラップする必要はありませんが、同じ利点があります。このような何か作業をする必要があります:
import pyvirtualdisplay
with pyvirtualdisplay.Display(visible=0, size=(800, 600)):
// it can crash here doing other things
EDIT:あなたのコードが産卵されているため、stopメソッドの呼び出しは、この特定の場合には重要である(そして、あなたはほぼ確実にメモリリークについての権利である理由)という理由がありますXvfbサブプロセスは仮想ディスプレイとして機能します。 stopメソッドはこのサブプロセスを終了させます。したがって、サブプロセスが呼び出されない場合は、&の実行中はinitプロセスに戻ります。このhereに関する詳細(「ゾンビと孤児のプロセス」セクション)があります。
私は、これは、コードのこの単純なビットを使用してどのように機能するかを確認することができました:
import time
from pyvirtualdisplay import Display
display = Display(visible=0, size=(800, 600))
display.start()
print('About to sleep')
time.sleep(20)
raise Exception('Oh noes!')
display.stop()
私は、Pythonスクリプトの前と後(Xvfbのプロセスのプロセスツリーを表示するには)私のシェルでpstree -sA $(pgrep Xvfb)
を走りました墜落したPythonスクリプトがクラッシュした後
systemd---xfce4-terminal---zsh---python---Xvfb-+-{llvmpipe-0}
|-{llvmpipe-1}
|-{llvmpipe-2}
`-{llvmpipe-3}
:我々はXvfbのプロセスの親プロセスが(その親など、私の端末エミュレータである親が私のシェルである、)のpythonであることがわかりますクラッシュする前に
プロセスがinitプロセスに親子化されました(私の場合、これはsystemdですが、あなたの場合は他のinitシステムかもしれません)。
systemd---Xvfb-+-{llvmpipe-0}
|-{llvmpipe-1}
|-{llvmpipe-2}
`-{llvmpipe-3}
短い答えは、表示された場所でコードがクラッシュした場合、display.sendstop()が呼び出されないということです。スクリプトはクラッシュしているので、OSは開いているハンドラをすべて閉じないでください。 – Saurabh
'短い答えは、表示された場所でコードがクラッシュした場合にdisplay.sendstop()が呼び出されないということです。' - そうでないとします。スクリプトがクラッシュしたため、OSは開いているすべてのハンドラを閉じないのですか? – Saurabh
私が作った編集がこれをより良く説明してくれることを願っています。 答えはいいえ - PyVirtualDisplayは、スクリプトが終了した後も残っているサブプロセスを作成しています。 – joelnb