2012-12-30 12 views
6

मैंने पायथन में itertools.permutations फ़ंक्शन के साथ क्रमपरिवर्तन उत्पन्न किए हैं।पायथन क्रमपरिवर्तन धागे

perms = itertools.permutations('1234', r=4) 

#I would like to iterate through 'perms' with multiple threads 
for perm in perms: 
    print perm 
+0

आप थ्रेड के बीच डेटा को कैसे विभाजित करना चाहते हैं? आप एकाधिक धागे का उपयोग क्यों करना चाहते हैं? –

+0

मैं इसे समान रूप से विभाजित करना चाहता हूं: यदि 'परम्स' में 1'000'000 प्रविष्टियां हैं और मेरे पास 4 धागे हैं तो प्रत्येक धागे को 250'000 प्रविष्टियों को संसाधित करना चाहिए; अगर मैं केवल एक थ्रेड का उपयोग करता हूं तो पूरे प्रविष्टियों के माध्यम से लगभग 10 मिनट लगते हैं इसलिए मैं एक से अधिक धागे – wasp256

+0

का उपयोग करना चाहता हूं, आपकी प्रक्रिया बिल्कुल ठीक है, आईओ बाध्य या सीपीयू बाध्य है? –

उत्तर

4

यदि आप क्रमपरिवर्तन जनरेटर से आइटम के साथ काम करना चाहते हैं तो सीपीयू गहन है, तो आप शायद धागे की बजाय प्रक्रियाओं का उपयोग करना चाहते हैं। सीपीथॉन का ग्लोबल इंटरप्रेटर लॉक (जीआईएल) सीपीयू बाध्य काम करते समय सीमित मूल्य के बहुप्रचार को बनाता है।

इसके बजाय, इसलिए जैसे multiprocessing मॉड्यूल के Pool वर्ग, का उपयोग करें:

import multiprocessing 
import itertools 

def do_stuff(perm): 
    # whatever 
    return list(reversed(perm)) 

if __name__ == "__main__": 
    with multiprocessing.Pool() as pool: # default is optimal number of processes 
     results = pool.map(do_stuff, itertools.permutations('1234', r=4)) 

     # do stuff with results 

ध्यान दें कि आप results से अधिक पुनरावृत्ति हो जाएगा अगर (बजाय एक सूची के रूप में यह साथ कुछ कर), तो आपको imap के बजाय का उपयोग कर सकते map एक पुनरावर्तक प्राप्त करने के लिए जिसका उपयोग आप परिणामों पर काम करने के लिए कर सकते हैं क्योंकि वे कार्यकर्ता प्रक्रियाओं से उत्पादित होते हैं। यदि इससे कोई फ़र्क नहीं पड़ता कि आइटम किस प्रकार लौटाए जाते हैं, तो आप imap_unordered (मुझे लगता है) का उपयोग कुछ स्मृति को सहेजने के लिए कर सकते हैं।

if __name__ is "__main__" बॉयलरप्लेट विंडोज़ पर आवश्यक है, जहां multiprocessing मॉड्यूल को ओएस की सीमाओं के आसपास काम करना है (fork)।

0

पायथन के futures मॉड्यूल यह बनाता है: समस्या यह है कि परिणाम बहुत बड़ा है और मैं एक से अधिक थ्रेड के साथ के माध्यम से जाना है, लेकिन वास्तव कि यहाँ पूरा करने के लिए पता नहीं कैसे चाहते हैं क्या मैं अब तक किया है धागे के बीच काम विभाजित करने के लिए आसान है। इस उदाहरण में, 4 धागे का उपयोग किया जाएगा, लेकिन आप अपनी आवश्यकताओं के अनुरूप इसे संशोधित कर सकते हैं।

from concurrent import futures 

def thread_process(perm): 
    #do something 

with futures.ThreadPoolExecutor(max_workers=4) as executor: 
    for perm in perms: 
     executor.submit(thread_process, perm) 
+0

द्वारा किया जाना चाहिए थ्रेडिंग का उपयोग करने में समस्या यह है कि यह ऐसा नहीं करेगा जो ओपी चाहता है क्योंकि जीआईएल की वजह से यह समानांतर –

+0

में निष्पादित नहीं होता है, मुझे नहीं लगता कि वह कहता है कि "एकाधिक धागे से गुज़रने" का अर्थ क्या है - वह सॉकेट/फ़ाइल कॉल करने के लिए एक और प्रक्रिया को निष्पादित करने से कुछ भी कर सकता है जो धागे को अवरुद्ध करता है। इन परिदृश्यों में जीआईएल कोई समस्या नहीं पैदा करेगा। मैं मानता हूं कि यह निश्चित रूप से निर्भर करता है कि वह क्या करना चाहता है। –

1

अपने प्रसंस्करण समारोह मान लिया जाये कि f (x) आप धागे का उपयोग कर, समानांतर में प्रक्रियाओं पर अमल नहीं होता है जब तक यह आईओ बाध्य है,

from multiprocessing import Pool 

def f(x): 
    return x*x 

if __name__ == '__main__': 
    pool = Pool(processes=4) # start 4 worker processes 
    perms = itertools.permutations('1234', r=4) 
    for r in pool.map(f, perms): 
     print (r) 

वास्तव में क्या करना चाहते हैं है। यदि यह सीपीयू बाध्य है और आपके पास क्वाड कोर है, तो यह जाने का तरीका है। यदि आपके पास मल्टीकोर नहीं है और यह सीपीयू बाध्य है, तो मुझे डर है कि इसे समानांतर बनाने से आपकी वर्तमान स्थिति में सुधार नहीं होगा।

1

स्प्लिट धागे के बीच perms की संख्या का सूचकांक तो this function का उपयोग नहीं बल्कि सभी perms पैदा करने और उन्हें धागे के बीच बंटवारे से प्रत्येक सूत्र में अपने सूचकांक से पर्म उत्पन्न करने के लिए।

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