Python tkinter多处理pickle错误
在Python 2.7.11中。我有一个tkinter GUI,用户在其中将文件输入列表框。运行按钮应该读取每个文件并将数据插入数据库。我需要读数是串联的,而不是并联的。我想在单独的进程中运行读取。作为测试,我在tkinter之外运行了以下代码,得到了预期的结果。。。当读者仍在后台吃力地工作时,主线程似乎结束了Python tkinter多处理pickle错误,python,tkinter,multiprocessing,Python,Tkinter,Multiprocessing,在Python 2.7.11中。我有一个tkinter GUI,用户在其中将文件输入列表框。运行按钮应该读取每个文件并将数据插入数据库。我需要读数是串联的,而不是并联的。我想在单独的进程中运行读取。作为测试,我在tkinter之外运行了以下代码,得到了预期的结果。。。当读者仍在后台吃力地工作时,主线程似乎结束了 import multiprocessing as mp import time import F06 def _worker(li): for path in li:
import multiprocessing as mp
import time
import F06
def _worker(li):
for path in li:
print('worker is processing:={}'.format(path))
reader = F06.Reader()
reader.read_sol_106(path)
time.sleep(0.5)
print('process complete')
if __name__ == '__main__':
# make a list of files to read
li = [
'Results/1201301__SOL106.f06',
'Results/1201302__SOL106.f06',
'Results/1201303__SOL106.f06',
]
p = mp.Process(target=_worker, args=(li,))
p.start()
print('main thread finished')
我试图以类似的方式将代码添加到tkinter程序中,但无法使其运行。tkinter GUI在一个类中,不确定这是否导致了问题,仅供参考。这是以下错误反馈:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1537, in __call__
return self.func(*args)
File "C:\Users\00835182\Documents\METHODS\01_PET_PROJECTS\13_Py_SQL\DB_GUI.py", line 122, in run
p.start()
File "C:\Python27\lib\multiprocessing\process.py", line 130, in start
self._popen = Popen(self)
File "C:\Python27\lib\multiprocessing\forking.py", line 277, in __init__
dump(process_obj, to_child, HIGHEST_PROTOCOL)
File "C:\Python27\lib\multiprocessing\forking.py", line 199, in dump
ForkingPickler(file, protocol).dump(obj)
File "C:\Python27\lib\pickle.py", line 224, in dump
self.save(obj)
File "C:\Python27\lib\pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "C:\Python27\lib\pickle.py", line 425, in save_reduce
save(state)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 655, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 687, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\multiprocessing\forking.py", line 67, in dispatcher
self.save_reduce(obj=obj, *rv)
File "C:\Python27\lib\pickle.py", line 401, in save_reduce
save(args)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 554, in save_tuple
save(element)
File "C:\Python27\lib\pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "C:\Python27\lib\pickle.py", line 425, in save_reduce
save(state)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 655, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 687, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 731, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 655, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 687, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 731, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 655, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 687, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 731, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 655, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 687, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 655, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 687, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 731, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 655, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 687, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 313, in save
(t.__name__, obj))
PicklingError: Can't pickle 'tkapp' object: <tkapp object at 0x024932F0>
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Python27\lib\multiprocessing\forking.py", line 381, in main
self = load(from_parent)
File "C:\Python27\lib\pickle.py", line 1384, in load
return Unpickler(file).load()
File "C:\Python27\lib\pickle.py", line 864, in load
dispatch[key](self)
File "C:\Python27\lib\pickle.py", line 886, in load_eof
raise EOFError
EOFError
我已经准备好学习你能教给我的任何东西。与其使用多处理模块,即调用Popen,不如直接尝试使用Popen,我不知道这是否可行,但值得一试。此方法不应导致调用pickle 在名为worker.py的单独文件中
import time
import F06
import sys
import argparse
if sys.argc == 0:
sys.exit(1)
for path in sys.argv:
print('worker is processing:={}'.format(path))
reader = F06.Reader()
reader.read_sol_106(path)
time.sleep(0.5)
print('process complete')
然后在主文件中
from subprocess import Popen, PIPE
if __name__ == '__main__':
# make a list of files to read
cmd = [
'python',
'worker.py',
'Results/1201301__SOL106.f06',
'Results/1201302__SOL106.f06',
'Results/1201303__SOL106.f06',
]
p = Popen(cmd, stderr=PIPE, stdout=PIPE)
out, err = p.communicate()
print('main thread finished')
这是因为多重处理是通过酸洗对象并将其传递给其他进程来实现的。我打赌你不需要进程,只需要线程。Pickle无法转储tkinter对象,这就是出现此错误的原因。如果你不需要并行化繁重的计算,你应该使用threads@dgan最初我尝试使用线程。不过,我无法得到我想要的行为。线程完成后,它继续运行。当我使用.join停止它时,它会阻塞主线程。我试着打电话给他。之后。我试了好几个小时,阅读了我能找到的关于这个问题的所有资料,但都没有成功。我现在使用多处理,因为我不需要进程之间的通信,也不需要共享资源。但根据你的评论,这听起来似乎是不可能的。我坚持确认,这绝对是你需要的线索。如果您需要线程在父线程死亡后死亡,那么可以将其设置为deamon=True。连接线程是阻塞,这是正常的。否则你有没有看过?另外,您可以像往常一样从线程返回,以便离开它。多处理是一个完全合理的解决方案。您只是不能从其他进程引用任何tkinter对象。相反,让流程将项目放在GUI线程可以操作的队列上。
from subprocess import Popen, PIPE
if __name__ == '__main__':
# make a list of files to read
cmd = [
'python',
'worker.py',
'Results/1201301__SOL106.f06',
'Results/1201302__SOL106.f06',
'Results/1201303__SOL106.f06',
]
p = Popen(cmd, stderr=PIPE, stdout=PIPE)
out, err = p.communicate()
print('main thread finished')