Python tkinter多处理pickle错误

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:

在Python 2.7.11中。我有一个tkinter GUI,用户在其中将文件输入列表框。运行按钮应该读取每个文件并将数据插入数据库。我需要读数是串联的,而不是并联的。我想在单独的进程中运行读取。作为测试,我在tkinter之外运行了以下代码,得到了预期的结果。。。当读者仍在后台吃力地工作时,主线程似乎结束了

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')