pygtk gui 因 pyjack 线程而冻结
我有一个程序可以通过插孔连接记录来自火线设备(FA-66)的音频。 该界面是使用 pygtk 创建的,并使用 py-jack 进行录制(http://sourceforge.net/projects /py-jack/)。 录制是在不同的线程中完成的,因为必须同时使用 GUI 来查看音频结果。
问题是当我启动录制线程时,GUI 的响应速度变得非常慢。 我在主线程的开头有 gtk.gdk 函数 start_threads() 。 如果我做对了,我不需要threads_enter()和threads_leave(),因为录制不会影响GUI。 如果我错了,请纠正。
函数 jack.process() 从三个麦克风录制音频。 例如,如果我将其替换为 time.sleep(2),则一切正常。
在这种情况下创建线程的最佳方法是什么? 为什么 jack.process 会冻结 GUI? 是否占用了所有的CPU时间或者其他什么? 我的代码示例如下:
soundrecorder.py:
...
def start(self):
Thread(target=self._start).start()
def _start(self):
while self.eventhandler.record.isSet():
data = self._jackRecord(self.sample_length)
self.datahandler.queue.put(data)
def _jackRecord(self, length):
capture = Numeric.zeros((self.inputs, int(self.sample_rate * length)), 'f')
output = Numeric.zeros((self.inputs, self.buffer_size), 'f')
i = 0
while i < capture.shape[1] - self.buffer_size:
try:
jack.process(output, capture[:,i:i+self.buffer_size])
i += self.buffer_size
except:
pass
return capture
eventhandler.py: recordStart() 和 recordStop() 只是按下开始和停止按钮时调用的回调函数。
...
def recordStart(self, widget, data=None):
if not self.record.isSet():
self.record.set()
self.soundrecorder = SoundRecorder(self, self.datahandler)
self.soundrecorder.connect()
self.soundrecorder.start()
def recordStop(self, widget, data=None):
if self.record.isSet():
self.record.clear()
del(self.soundrecorder)
I have a program that records audio from firewire device (FA-66) with Jack connection. The interface is created with pygtk and the recording with py-jack (http://sourceforge.net/projects/py-jack/). The recording is done in a different thread because the GUI must be used at the same time for viewing results from the audio.
The problem is that when I start the recording thread, the GUI becomes very slow to respond. I have gtk.gdk function start_threads() at the beginning of the main thread. If I've got it right, I don't need threads_enter() and threads_leave(), because the recording doesn't affect the GUI. Please correct if I'm wrong.
The function jack.process() records audio from three microphones. If I replace it, for example, with time.sleep(2), everything works ok.
What is the best way to create threading in this case? Why does the jack.process freeze the GUI? Does it take all the cpu time or something?
Samples of my code below:
soundrecorder.py:
...
def start(self):
Thread(target=self._start).start()
def _start(self):
while self.eventhandler.record.isSet():
data = self._jackRecord(self.sample_length)
self.datahandler.queue.put(data)
def _jackRecord(self, length):
capture = Numeric.zeros((self.inputs, int(self.sample_rate * length)), 'f')
output = Numeric.zeros((self.inputs, self.buffer_size), 'f')
i = 0
while i < capture.shape[1] - self.buffer_size:
try:
jack.process(output, capture[:,i:i+self.buffer_size])
i += self.buffer_size
except:
pass
return capture
eventhandler.py:
recordStart() and recordStop() are simply callback functions that are called when start and stop buttons are pressed.
...
def recordStart(self, widget, data=None):
if not self.record.isSet():
self.record.set()
self.soundrecorder = SoundRecorder(self, self.datahandler)
self.soundrecorder.connect()
self.soundrecorder.start()
def recordStop(self, widget, data=None):
if self.record.isSet():
self.record.clear()
del(self.soundrecorder)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您误解了线程的工作原理。
在这种情况下,线程对您没有帮助。
错误。线程不会同时做两件事。在 python 中,有一个全局锁可以防止两个线程同时运行 python 代码或接触 python 对象 两件事不会同时发生。线程机制只是在它们之间切换,每次执行固定数量的指令。
除此之外,如果没有两个 CPU 或内核,则 与单线程相比,使用线程的 Python 代码的处理、内存和代码复杂性开销没有任何好处,并且性能较低。此规则只有少数例外,
您可能希望将录制循环重写为回调并将其与 GTK 循环集成(
为此 ,您将获得比使用线程更好的性能)。 ,使用
gobject.idle_add
具有很大的优先级。
如果您想使用两个处理器/核心“同时”运行两件事,您需要启动另一个进程。 启动一个进程来收集数据,并通过某种进程间通信机制将其传输到正在分析和绘制数据的另一个进程。 multiprocessing 模块可以帮助您。
You misunderstand how threads work.
Threads don't help you in this case.
WRONG. Threads don't do two things at the same time. In python there's a global lock that prevent two threads from running python code or touching python objects at the same time. And besides that, two things don't ever happen at the same time if you don't have two CPUs or cores. The threading mechanism just switches between them executing a fixed number of instructions of each at a time.
Threads also add a processing, memory and code complexibility overhead for no benefit. Python code using threads run slower and have lower performance than if it was single-threaded. There are only a few exceptions for this rule and your case is not one of them.
You probably want to rewrite your recording loop as a callback and integrate it with the GTK loop (you'll get better performance than using threads).
For that, use a
gobject.idle_add
with a big priority.If you want to run two things really at "the same time", using two processors/cores, you want to launch another process. Launch a process to collect data and transmit it via some inter-process communication mechanism to the other process that is analizing and plotting data. multiprocessing module can help you with that.