我在pygtk中编写了一个工具,它需要处理递归解析大型目录,并将结果匹配的文件添加到列表中。这个过程显然会导致用户界面挂起,所以我试图使用多处理库。多线程 - 设计或代码问题时出现酸洗错误?
一些更多的背景,然后再问我一些解决方案: - 该程序有两个主要的类,一个控制器类,完成所有密集的工作并对UI讲话,一个Model类,用于处理所有数据工具需求。
import sys
import os
import pygtk
import fnmatch
from multiprocessing import Pool
pygtk.require("2.0")
#try:
from gi.repository import Gtk
from gi.repository import GObject
#except:
# print("GTK Not Availible")
# sys.exit(1)
class Controller(object):
def __init__(self,builder,model):
self.builder=builder
self.model=model
def btn_pass_clicked(self, *args,**kwargs):
print "it's working!, its woooooorkkinnnnggg!"
spinnywheel= self.builder.get_object("activitySpinner")
spinnywheel.start()
def btn_fail_clicked(self, *args, **kwargs):
print "stopping spinnywheel!"
spinnywheel=self.builder.get_object("activitySpinner")
spinnywheel.stop()
def quit(self,*args,**kwargs):
print "iamquit"
Gtk.main_quit()
def file_menu_open(self,*args,**kwargs):
print "file->open"
self.builder.get_object("openDialogue").show()
def opendialogue_btnOpen_clicked(self,*args,**kwargs):
rootdir = os.path.expanduser(self.builder.get_object("openDialogue_entryBox").get_text())
self.builder.get_object("openDialogue").hide()
self.builder.get_object("openDialogue_entryBox").set_text("")
if os.path.exists(rootdir):
self.builder.get_object("activitySpinner").start()
print "pooling workers and walking ",rootdir
p = Pool(None)
p.apply_async(self.walk_for_files,rootdir,None,self.finished_recurse)
else:
print "Path does not exist!"
def walk_for_files(self,rootdir):
for root,dirs,files in os.walk(rootdir):
for extension in ['c','cpp']:
for filename in fnmatch.filter(files,'*.'+extension):
self.model.add_single_file(os.path.join(root,filename))
def finished_recurse(self,*args,**kargs):
print "workers finished parsing dirs!"
self.builder.get_object("activitySpinner").stop()
class Model(object):
def __init__(self):
self.fileList=[]
def add_single_file(self,file):
self.fileList.append(file)
print "added ",file
class Scrutiny(object):
def __init__(self):
builder = Gtk.Builder()
builder.add_from_file("scrutinydev.ui")
model_object=Model()
controller_object=Controller(builder,model_object)
builder.connect_signals(controller_object)
builder.get_object("windowMain").show()
builder.get_object("listView")
GObject.threads_init()
Gtk.main()
if __name__ == "__main__":
scrutiny = Scrutiny()
现在,继承人我的问题。
正如您所看到的,使用pool()生成的工作人员需要执行回调finish_recurse,以便在其他UI工作中停止GtkSpinner。
随着其当前状态的代码,我得到一个错误的酸洗,
PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
我明白,这是因为我无法序列化回调,并想为为了解决方法/修复建议实现我所需要的。
看看http://www.frozentux.net/2010/05/python-multiprocessing/;会帮助你吗? – 2012-07-27 09:40:24
问题是,一个方法不包含告诉你它定义了哪个类的信息,这使得它不可能被腌制。我认为这可能会在未来版本的python中被修复(请参见[PEP 3155](http://www.python.org/dev/peps/pep-3155/)和[PEP 3154](http:// www .python.org/dev/peps/pep-3154 /)),但现在,您可以将'finished_recurse'转换为模块级功能。 – James 2012-07-27 09:49:47
谢谢,我会看看那个链接martijn,但同时@james,你能详细说明代码中可能的样子吗?我是所有OO术语的新手。阅读:“我如何声明模块级功能?” – tel0s 2012-07-27 09:55:55