In Python 2.7.11. I have a tkinter GUI where the user enters files into a Listbox. The RUN button is supposed to read each file and insert data into a database. I need the reading to be in series, not parallel. I want to run the reading in a separate process. I ran the following code outside of tkinter, as a test, and I got the desired results... The main thread appears to finish while the reader is still chugging along in the background.
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')
I tried adding the code in a similar fashion to my tkinter program and I cannot get it to run. The tkinter GUI is in a class, not sure if this is contributing to the problem, just FYI. This is the following error feedback:
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
I am not sure, but the problem my lie in the 'self' argument. My code, at least what I think are the relevant portions are:
def run(self): # ... linked to "Run" button 'command'
f06_files = self.frame_2_listbox.get(0, 'end') # ............. get List of results files
p = multiprocessing.Process(target=self._run, args=(f06_files,))
# this also did not work
# p = multiprocessing.Process(target=self._run, args=(None, f06_files))
p.start()
def _run(self, li):
num_files = len(li) # ........................................ total number of file
file_counter = 0 # ........................................... file counter
for path in li: # ............................................ iterate over files
file_counter += 1 # ...................................... increment file counter
s = 'File {} of {}'.format(file_counter, num_files) # . string msg to user
print(s)
# read the results file
reader = Reader() # ...................................... instantiate Reader, clears for reuse
reader.read_sol_106(path) # .............................. read results file, extract loads
# retrieve loads
bars = reader.get_bar_forces() # ......................... List of Tuples
beams = reader.get_beam_forces() # .......................
bushs = reader.get_bush_forces() # .......................
cons = reader.get_con_forces() # .........................
rods = reader.get_rod_forces() # .........................
shells = reader.get_shell_forces() # .....................
gaps = reader.get_gap_forces() # .........................
springs = reader.get_spring_forces() # ...................
# insert loads into database
self.insert_data(file=path, bars=bars, beams=beams, bushs=bushs, cons=cons, rods=rods, shells=shells, gaps=gaps, springs=springs)
I'm ready to learn whatever you can teach me.