【发布时间】:2012-02-14 10:57:48
【问题描述】:
我有一个设计用于在 Windows 和 Ubuntu 上运行的 pygtk 程序。它是 Python 2.7 和带有静态绑定的 gtk2(即没有 gobject 自省)。我遇到的问题在 Ubuntu 上存在,但在 Windows 上不存在。
我的程序应该能够处理大量文件(这里我测试了大约 200 个文件),但每个文件的实际处理量并不多。我按文件排队处理并向用户展示进度。
问题是,在使用 gtk.FileChooserDialog 选择文件后(control-A 是你的朋友),程序挂起并且 gtk 事件在很长一段时间内都没有处理 - 即使我的回调函数已经返回。在此期间,所有内核的 CPU 使用率都保持在 80% 左右,iotop 显示我的进程正在以大约每秒 20MB 的速度写入磁盘,并且其他应用程序间歇性地无响应 - Chrome、Xorg、compiz 、banshee 和 gedit 的 CPU 使用率都很高(在选择文件之前使用率很低)。
这是一些示例代码。要重现,请单击按钮,从某处选择大约 200 个文件(大约十个屏幕值得按住 shift 和 down),然后单击 OK。什么文件无关紧要 - 对它们什么都不做。
import gtk,gobject,time
def print_how_long_it_was_frozen():
print time.time() - start_time
def button_clicked(button):
dialog = gtk.FileChooserDialog(
'Select files to add', w, gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_select_multiple(True)
dialog.set_default_response(gtk.RESPONSE_OK)
response = dialog.run()
files = dialog.get_filenames()
dialog.destroy()
for i, f in enumerate(files):
print i
global start_time
start_time = time.time()
gobject.idle_add(print_how_long_it_was_frozen)
w = gtk.Window()
b = gtk.Button('Select files')
w.add(b)
b.connect('clicked', button_clicked)
w.show_all()
gtk.main()
这会导致回调结束后约 60 秒挂起,在此期间,除了正在处理对话框的销毁(在挂起过程中发生)之外,什么都不会发生。
那是在 Ubuntu 11.10 上。在 Windows 上,挂起时间不到一秒。
我怀疑这是由于某些 Gnome 或 Unity 的“最近文件”功能或其他活动跟踪所致。进程 zeitgeist-daemon 在挂起期间 CPU 使用率也很高,但杀死它并不能解决问题。使用 Zeitgeist 活动日志管理器也不会禁用日志记录。即使可以禁用 Zeitgeist,我也不能指望我的用户禁用它。
有谁知道如何禁用 gtk 应用程序对最近文件的报告,或者知道其他任何可能导致此问题的原因?
必须通过“选择文件夹”对话框添加大量文件以进行处理,但对于较少数量的文件,每个文件的挂起时间似乎约为半秒,这实际上是不可接受的对于其他响应式应用。
(在 32 位 Windows 7 和 64 但 Ubuntu 11.10 上完成测试。Python 2.7 和 pygtk 2.24 都在)
【问题讨论】:
标签: python ubuntu filesystems gtk