2011-11-23 13 views
5

मैं multiprocessing.Pool का उपयोग कर एक टैरिफाइल की सामग्री को संसाधित करने का प्रयास कर रहा हूं। मैं मल्टीप्रोसेसिंग मॉड्यूल के भीतर थ्रेडपूल कार्यान्वयन का सफलतापूर्वक उपयोग करने में सक्षम हूं, लेकिन थ्रेड की बजाय प्रक्रियाओं का उपयोग करने में सक्षम होना चाहता हूं क्योंकि यह संभवतः तेज़ होगा और मल्टीथ्रेडेड वातावरण को संभालने के लिए मैटलप्लिब के लिए किए गए कुछ बदलावों को खत्म कर देगा। मैं एक त्रुटि है कि मुझे लगता है पता स्थान साझा नहीं कर प्रक्रियाओं से संबंधित है हो रही है, लेकिन मुझे यकीन है कि यह कैसे तय करने के लिए नहीं कर रहा हूँ:मैं पाइथन मल्टीप्रोसेसिंग पूल के साथ टैरिफाइल को कैसे संसाधित कर सकता हूं?

Traceback (most recent call last): 
    File "test_tarfile.py", line 32, in <module> 
    test_multiproc() 
    File "test_tarfile.py", line 24, in test_multiproc 
    pool.map(read_file, files) 
    File "/ldata/whitcomb/epd-7.1-2-rh5-x86_64/lib/python2.7/multiprocessing/pool.py", line 225, in map 
    return self.map_async(func, iterable, chunksize).get() 
    File "/ldata/whitcomb/epd-7.1-2-rh5-x86_64/lib/python2.7/multiprocessing/pool.py", line 522, in get 
    raise self._value 
ValueError: I/O operation on closed file 

वास्तविक कार्यक्रम और अधिक जटिल है, लेकिन इस का एक उदाहरण है क्या मैं कर रहा हूँ कि त्रुटि reproduces:

from multiprocessing.pool import ThreadPool, Pool 
import StringIO 
import tarfile 

def write_tar(): 
    tar = tarfile.open('test.tar', 'w') 
    contents = 'line1' 
    info = tarfile.TarInfo('file1.txt') 
    info.size = len(contents) 
    tar.addfile(info, StringIO.StringIO(contents)) 
    tar.close() 

def test_multithread(): 
    tar = tarfile.open('test.tar') 
    files = [tar.extractfile(member) for member in tar.getmembers()] 
    pool = ThreadPool(processes=1) 
    pool.map(read_file, files) 
    tar.close() 

def test_multiproc(): 
    tar = tarfile.open('test.tar') 
    files = [tar.extractfile(member) for member in tar.getmembers()] 
    pool = Pool(processes=1) 
    pool.map(read_file, files) 
    tar.close() 

def read_file(f): 
    print f.read() 

write_tar() 
test_multithread() 
test_multiproc() 

मुझे लगता है कि कुछ गलत है जब TarInfo वस्तु अन्य प्रक्रिया में पारित हो जाता है, लेकिन माता-पिता TarFile नहीं है, लेकिन मुझे यकीन है कि कैसे में इसे ठीक करने नहीं कर रहा हूँ मल्टीप्रोसेस केस। क्या मैं इसे टैरबॉल से फ़ाइलों को निकालने और डिस्क पर लिखने के बिना कर सकता हूं?

उत्तर

5

आप अन्य प्रक्रिया में एक TarInfo वस्तु गुजर नहीं कर रहे हैं, तो आप अन्य प्रक्रिया है जहाँ member एक TarInfo वस्तु है में tar.extractfile(member) का परिणाम गुजर रहे हैं। extractfile(...) विधि फ़ाइल की तरह ऑब्जेक्ट देता है जिसमें अन्य चीजों के साथ read() विधि है जो tar = tarfile.open('test.tar') के साथ खोले गए मूल टैर फ़ाइल पर चलती है।

हालांकि, आप किसी अन्य प्रक्रिया में एक प्रक्रिया से खुली फ़ाइल का उपयोग नहीं कर सकते हैं, आपको फ़ाइल को फिर से खोलना होगा। मैं इस के साथ अपने test_multiproc() लाए गए:

def test_multiproc(): 
    tar = tarfile.open('test.tar') 
    files = [name for name in tar.getnames()] 
    pool = Pool(processes=1) 
    result = pool.map(read_file2, files) 
    tar.close() 

और यह कहा:

def read_file2(name): 
    t2 = tarfile.open('test.tar') 
    print t2.extractfile(name).read() 
    t2.close() 

और अपने कोड काम कर पाने में सक्षम था।

+0

विंडोज़ समर्थन: 'अगर नाम ==' __main__ ': test_multiproc() '। विंडोज़ में कोई कांटा नहीं है, इसलिए मॉड्यूल को '__parents_main __' नाम से शुरू में नई प्रक्रिया में आयात किया जाता है, और फिर नाम बदलकर '__main __' 'हो जाता है। तो आप 'if' ब्लॉक का उपयोग करके बाल प्रक्रियाओं में भाग लेने के लिए कथन की रक्षा नहीं कर सकते हैं। – eryksun

+0

यह काम करता है, लेकिन मुझे हर प्रक्रिया में टैरिफाइल को फिर से खोलने की आवश्यकता है। क्या कोई अन्य कामकाज है जो प्रक्रियाओं के बीच फ़ाइल डिस्क्रिप्टर को केवल पढ़ने के लिए अनुमति देता है? –

+0

मैंने एकाधिक प्रक्रियाओं को बंद करने से पहले डेटा को पूर्व-पढ़ने के लिए ध्वज सेट करना समाप्त कर दिया। धन्यवाद! –

संबंधित मुद्दे