[英]Python: pickle error with multiprocessing
如下所示,我将代码更改为使用Pool。 我还简化了功能,并在下面包含了所有代码。 但是,现在我得到了另一个错误:NameError:未定义全局名称'split_files'
我想做的是将实际的文件块传递给parse_csv_chunk函数,但是我不确定该怎么做。
import csv
from itertools import islice
from collections import deque
import time
import math
import multiprocessing as mp
import os
import sys
import tempfile
csv_filename = 'test.csv'
def parse_csv_chunk(files_index):
global split_files
print files_index
print len(split_files)
return 1
def split(infilename, num_chunks):
READ_BUFFER = 2**13
in_file_size = os.path.getsize(infilename)
print 'Original file size:', in_file_size
chunk_size = in_file_size // num_chunks
print 'Target chunk size:', chunk_size
print 'Target number of chunks:', num_chunks
files = []
with open(infilename, 'rb', READ_BUFFER) as infile:
infile.next()
infile.next()
infile.next()
for _ in xrange(num_chunks):
temp_file = tempfile.TemporaryFile()
while temp_file.tell() < chunk_size:
try:
#write 3 lines before checking if still < chunk_size
#this is done to improve performance
#the result is that each chunk will not be exactly the same size
temp_file.write(infile.next())
temp_file.write(infile.next())
temp_file.write(infile.next())
#end of original file
except StopIteration:
break
#rewind each chunk
temp_file.seek(0)
files.append(temp_file)
return files
if __name__ == '__main__':
start = time.time()
num_chunks = mp.cpu_count()
split_files = split(csv_filename, num_chunks)
print 'Number of files after splitting: ', len(split_files)
pool = mp.Pool(processes = num_chunks)
results = [pool.apply_async(parse_csv_chunk, args=(x,)) for x in range(num_chunks)]
output = [p.get() for p in results]
print output
我正在尝试将csv文件拆分为多个部分,并由每个CPU内核对其进行处理。 这是我到目前为止的内容:
import csv
from itertools import islice
from collections import deque
import time
import math
import multiprocessing as mp
import os
import sys
import tempfile
def parse_csv_chunk(infile):
#code here
return
def split(infilename, num_chunks):
#code here
return files
def get_header_indices(infilename):
#code here
return
if __name__ == '__main__':
start = time.time() #start measuring performance
num_chunks = mp.cpu_count() #record number of CPU cores
files = split(csv_filename, num_chunks) #split csv file into a number equal of CPU cores and store as list
print 'number of files after splitting: ', len(files)
get_header_indices(csv_filename) #get headers of csv file
print headers_list
processes = [mp.Process(target=parse_csv_chunk,
args=ifile) for ifile in enumerate(files)] #create a list of processes for each file chunk
for p in processes:
p.start()
for p in processes:
p.join()
end = time.time()
print "Execution time: %.2f" % (end - start) #display performance
“ p.start()”行似乎有问题。 我在控制台上看到很多输出,最终表明存在错误:
pickle.PicklingError: Can't pickle <built-in method write of file object at 0x02
22EAC8>: it's not found as __main__.write
我没有包含我调用的函数的代码,因为它们很长,但是如果需要的话,我可以。 我想知道我是否正确使用了多处理。
首先,如果您有不使用的理由Pool
和imap
的方法Pool
?
其次,很难不看代码就说出任何细节,尤其是因为错误指向未提供的代码部分。
但是,您似乎已从提供的内容中正确使用了multiprocessing
-这是一个序列化问题。
请注意,如果使用dill
,则可以序列化write
方法。
>>> import dill
>>>
>>> f = open('foo.bar', 'w')
>>> dill.dumps(f.write)
'\x80\x02cdill.dill\n_get_attr\nq\x00cdill.dill\n_create_filehandle\nq\x01(U\x07foo.barq\x02U\x01wq\x03K\x00\x89c__builtin__\nopen\nq\x04\x89K\x00U\x00q\x05tq\x06Rq\x07U\x05writeq\x08\x86q\tRq\n.'
多数版本的multiprocessing
使用cPickle
(或C内置的pickle
版本),而dill
可以将其类型注入pickle
的python版本中,而C语言则不能这样做。
有一个dill
激活的multiprocessing
分支-因此您可以尝试一下,就像纯粹是一个酸洗问题一样,那么您应该通过multiprocess
克服它。
参见: https : //github.com/uqfoundation/multiprocess
编辑 (在OP更新之后):helper函数中的global
声明不能与pickle
。 为什么不只使用有效载荷函数(如split
)来读取文件的一部分并返回内容,或写入目标文件? 不要返回文件列表。 我知道它们是TemporaryFile
对象,但是除非您使用dill
(即使这样很敏感),否则您也不能腌制文件。 如果绝对需要,请返回文件名,而不是文件,并且不要使用TemporaryFile
。 pickle
会阻止尝试传递文件。 因此,您应该重构代码,或者像我之前建议的那样,尝试查看是否可以通过使用multiprocess
(使用dill
)来绕过序列化问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.