下载文件时,Twisted + GTK应用程序无响应

时间:2013-03-31 11:32:46

标签: gtk twisted pygtk

我想在同一个应用程序中使用Twisted和GTK +。我正在使用gtk2reactor,使我的所有代码都正常无阻塞,并且通常它运行良好。

然而,当我运行(HTTP)下载时,GUI变得没有响应且迟钝。这就像扭曲的块(非常短的时间段)和反应堆不经常处理GTK事件一样。基本上,我正在使用:

factory = twc.HTTPDownloader(url, filename)
reactor.connectTCP(host, port, factory)

这是展示问题的little PyGtk program。我只有一个虚拟进度条来显示一些动画,但问题在一个完整的程序中也很明显。只要下载正在运行,滚动或在GtkNotebook选项卡之间切换时就会出现明显的延迟。

这是预期的,还是我做错了什么?我以前做过GTK + Twisted应用程序并且从未注意到这一点,但之后我也从未在扭曲之前传输更大的文件(~300 MB)。也许扭曲选择太大的块大小并且在将控制权交还给主循环之前保持忙碌太长时间(~100ms?)?我应该为GTK和扭​​曲的循环使用单独的线程吗?

1 个答案:

答案 0 :(得分:1)

在我向您提供有关解决此问题的任何建议之前,我应该注意,每当遇到这样的性能问题时,您应该对应用程序进行概要分析,以了解花费最多时间的内容。您可以使用cProfile之类的分析器;或者statprof,或者this cool hack from Geoff Greer,或者是it is basically impossible to do,它专门用于确定什么阻碍了Twisted的反应堆。客观数据总是优于猜想,您的特定数据只能从您的特定环境中获取。

那就是说,我确实对你有一些猜想。这里的问题很可能是文件I / O.非阻塞文件I / O对于Twisted来说是一个痛处,因为blocking file writes不仅仅是一个线程,所以还不清楚如何构建一个最终适合未来特定于平台的API的可移植API 。尽管如此,扭曲的应该来为你提供一些东西来抽象出它的线程部分。

HTTPDownloader,具体而言,flow-control会使反应堆卡住并且您的GUI冻结。您可以覆盖pagePart来执行非阻塞操作;但是,这意味着您需要在HTTPPageDownloader对象的transport属性上执行deliverBody - 例如将它告诉pauseProducing - 如果你的磁盘速度很慢,你最终可能会在内存中缓冲所有~300MB的文件。

如果您使用新的Agent API,您可能会发现所有这些都更容易。您仍然需要执行自己的非阻止文件I / O,但至少we're working on it. API会为您提供一个transport对象,您可以使用pauseProducing方法直接访问该对象子类化几个不同的东西并涉及几个抽象层(ClientFactoryHTTPClientFactoryHTTPDownloaderHTTPPageDownloader)来访问它。

我意识到在Twisted中应该更容易管理流量控制,我很抱歉这个设置有点繁琐。我知道,{{3}}