在Python 2.7.11中。我有一个tkinter GUI,用户将文件输入到列表框中。 RUN按钮应该读取每个文件并将数据插入数据库。我需要读数是串联的,而不是平行的。我想在一个单独的过程中运行阅读。我在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在一个类中,不确定这是否导致问题,仅仅是FYI。这是以下错误反馈:
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
我不确定,但问题在于我在“自我”论证中的谎言。我的代码,至少我认为的相关部分是:
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)
我已准备好学习你能教给我的任何东西。
答案 0 :(得分:1)
不使用调用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')