我注意到在我通过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