2017-12-11 1 views
0

In Python 2.7.11. Ich habe eine tkinter GUI, wo der Benutzer Dateien in eine Listbox eingibt. Die RUN-Schaltfläche soll jede Datei lesen und Daten in eine Datenbank einfügen. Ich brauche das Lesen in Serie, nicht parallel. Ich möchte das Lesen in einem separaten Prozess durchführen. Ich habe den folgenden Code außerhalb von tkinter ausgeführt, als Test, und ich habe die gewünschten Ergebnisse ... Der Hauptthread scheint zu Ende zu sein, während der Leser noch im Hintergrund tuckert.tkinter multiprocessing pickle error

Ich habe versucht, den Code in ähnlicher Weise zu meinem Tkinter-Programm hinzufügen und ich kann es nicht zum Laufen bekommen. Die tkinter GUI ist in einer Klasse, nicht sicher, ob dies zu dem Problem beiträgt, nur zur Information. Dies ist das folgende Fehlerfeedback:

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 

Ich bin nicht sicher, aber das Problem meines liegt in dem ‚Selbst‘ Argumente. Mein Code, zumindest was ich denke sind die relevanten Teile sind:

Ich bin bereit zu lernen, was auch immer Sie mir beibringen können.

+0

Dies liegt daran, Multiprozessverarbeitung geschieht durch Beizen von Objekten und übergibt sie an andere Prozesse. Ich wette, dass Sie keinen "Prozess", sondern einen "Thread" brauchen. Pickle kann kein tkinter-Objekt ausgeben, deshalb haben Sie diesen Fehler. PS. Wenn Sie schwere Berechnungen nicht parallelisieren müssen, sollten Sie Threads verwenden – dgan

+0

@dgan Ursprünglich versuchte ich Threading. Ich konnte das Verhalten nicht erreichen, das ich wollte. Nachdem der Thread fertig war, lief er weiter. Wenn ich .join() verwendete, um es zu stoppen, würde es den Hauptthread blockieren. Ich habe Anrufe nach .after() versucht. Ich habe stundenlang versucht, alles auf dem Stapel zu lesen, was ich in der Ausgabe finden konnte, und es hat nie funktioniert. Der springende Punkt ist, die Benutzeroberfläche ansprechbar zu halten. – twegner

+0

Ich verwende jetzt Multiprocessing, weil ich keine Kommunikation zwischen Prozessen (geteilte Ressourcen) brauche. Aber es hört sich so an, als wäre das laut deinem Kommentar ein Nein. – twegner

Antwort

0

Anstatt das Multiprocessing-Modul zu verwenden, das Popen aufruft, versuchen Sie Popen direkt zu benutzen (ich weiß nicht, ob das funktioniert, aber es ist einen Versuch wert). Diese Methode sollte nicht dazu führen, dass der Aufruf einschenkt.

In einer separaten Datei mit dem Namen 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') 

dann in der Hauptdatei.

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