我注意到在我通過python使用gstreamer(使用Ubuntu 14.04的python-gst-1.0 deb軟件包版本1.2.0-1)之後,我似乎每個編碼器運行都有一個雜散線程。我在我寫的模塊中有gstreamer接口,它在模塊中執行gobject.mainloop,並且執行mainloop.quit(),所以我不希望它是主循環本身。Python gstreamer中的雜散線程使用
幾運行後,threading.enumerate()是表示:
[<_MainThread(MainThread, started 140079923849024)>,
<_DummyThread(Dummy-1, started daemon 140079768815360)>,
<_DummyThread(Dummy-3, started daemon 140079785338624)>,
<_DummyThread(Dummy-4, started daemon 140079418832640)>,
<_DummyThread(Dummy-2, started daemon 140079802386176)>]
值得慶幸的是,他們開始與守護程序,所以程序將退出,但我在一個不知如何清洗這些了。它們正在影響使用Ctrl-C退出腳本的可能性,因爲KeyboardInterrupt並不總是看起來像MainThread。我結束我的運行循環使用:
try:
time.sleep(899.0)
except KeyboardInterrupt:
pass
time.sleep(1.0)
這應該讓我按Ctrl-C快速兩倍於第一時間捕獲的try /除了中止循環超時,而第二個對1S沒有處理程序睡覺,從而退出。但是,對於流水線程,第二個Ctrl-C在某個層次上從未見過,所以我需要按Ctrl-Z才能到達shell並強制終止腳本。我不喜歡它。
任何人都知道這個流浪線程是什麼,以及如何讓它與我合作併爲我而死?我即將在正在運行的進程中斷開gdb以確定它可能是什麼。
的類代碼(剝離下來以去除不相關部分):
class GstEncoder:
def __init__(self, metadata, mediainfo):
self.error = None
# used for controlling logic which I removed for clarity
self.metadata = metadata
self.mediainfo = mediainfo
# Create a pipeline in self.pipeline
self.setupPipeline()
# Put in the MainLoop
self.mainloop = GObject.MainLoop()
self.context = self.mainloop.get_context()
self.abort = False
def __del__(self):
logger.info("Dying gasp!")
if self.mainloop.is_running():
self.mainloop.quit()
self.pipeline.unref()
def start(self):
# Set in playing mode
self.pipeline.set_state(Gst.State.PLAYING)
# actually only used in some situations, removed the controlling logic for clarity
GObject.timeout_add_seconds(900, self.timedOut)
GObject.timeout_add_seconds(30, self.progressReport)
try:
self.abort = False
self.mainloop.run()
except KeyboardInterrupt:
logger.warning("Aborted by Ctrl-C")
self.abort = True
self.mainloop.quit()
raise KeyboardInterrupt
# Stop the pipeline
self.pipeline.set_state(Gst.State.NULL)
return self.error
def progressReport(self):
position = self.pipeline.query_position(Gst.Format.TIME)[1]
duration = self.pipeline.query_duration(Gst.Format.TIME)[1]
if self.abort:
return False
percentage = 0.0 if duration == 0 \
else float(position)/float(duration) * 100.0
logger.info("Progress: %s/%s (%.2f%%)" % (Gst.TIME_ARGS(position),
Gst.TIME_ARGS(duration), percentage))
return True
def timedOut(self):
if self.abort:
return False
self.error = "Aborted by watchdog timer"
logger.warning(self.error)
self.abort = True
self.mainloop.quit()
return False
這被例示爲:https://s3.amazonaws.com/beirdo-share/before.png
我將需要一些示例代碼來回答,我一直在Python中使用gstreamer很多,從未遇到過這個問題。 (例如,對於每個編碼器運行,你的意思是什麼?) – 2014-11-02 15:12:57
每次運行時,我的意思是每次我實例化一個在其中執行gstreamer的類。我會很快用一些示例代碼更新這個問題。在你的mainloop完成並退出之後,你是否嘗試過使用「threading.enumerate()」,並且你沒有重新輸入管道? – Beirdo 2014-11-02 20:53:50
如果沒有實際的工作代碼,很難重現:)我相信這是其他代碼/設置的問題。例如,下面是代碼的精簡版,它不會出現任何問題:http://www.fpaste.org/147332/14979029/ – 2014-11-03 01:45:55