2012-12-30 16 views
6

Ho generato permute con la funzione itertools.permutations in python. Il problema è che il risultato è molto grande e vorrei passare attraverso di essa con più thread, ma non so davvero come fare che qui è quello che ho finora:Thread permutazioni Python

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

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

come si desidera dividere i dati tra i thread? perché vuoi usare thread multipli? –

+0

Vorrei dividerlo in modo uniforme: se 'permanenti' contiene 1'000'000 voci e ho 4 thread ogni thread dovrebbe elaborare 250'000 voci; Se uso solo un thread ci vogliono circa 10 minuti per passare attraverso le intere voci quindi vorrei usare più di un thread – wasp256

+0

che cosa è esattamente il tuo processo, vincolato all'IO o alla CPU? –

risposta

4

Se il lavoro che si desidera eseguire con gli elementi del generatore di permutazione richiede molta CPU, è probabile che si desideri utilizzare i processi anziché i thread. Il Global Interpreter Lock (GIL) di CPython rende multithreading di valore limitato durante il lavoro con CPU.

Invece, utilizzare la classe del modulo multiprocessingPool, in questo modo:

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 

Nota che se vi sarà l'iterazione results (piuttosto che fare qualcosa con esso come una lista), è possibile utilizzare imap invece di map per ottenere un iteratore che è possibile utilizzare per lavorare sui risultati così come vengono prodotti dai processi di lavoro. Se non importa quale ordine vengono restituiti gli articoli, è possibile utilizzare imap_unordered per (penso) salvare un po 'di memoria.

Il numero di targa if __name__ is "__main__" è richiesto su Windows, dove il modulo multiprocessing deve aggirare le limitazioni del sistema operativo (no fork).

0

modulo di Python futures rende lavoro facile da dividere tra i thread. In questo esempio, verranno utilizzati 4 thread, ma è possibile modificarlo in base alle proprie esigenze.

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

il problema con l'utilizzo del threading è che non farà ciò che l'OP vuole come a causa del GIL che non esegue in parallelo –

+0

Non vedo dove dice cosa intende per "passare attraverso più thread" - potrebbe fare qualsiasi cosa dall'esecuzione di un altro processo a effettuare chiamate socket/file che bloccano i thread. In questi scenari, GIL non causerà alcun problema. Sono d'accordo che dipende certamente da ciò che vuole fare. –

1

Assumendo che la funzione di elaborazione è f (x) che si vuole fare

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) 

Infatti, utilizzando thread non sarebbe eseguire i processi in parallelo, a meno che non sia legato IO. Se è collegato alla CPU e hai un quad core, allora è la strada da percorrere. Se non hai multicore ed è vincolato alla CPU, allora temo che renderlo parallelo non migliorerà la tua situazione attuale.

1

Split l'indicedel numero di permanenti tra fili quindi utilizzare this function per generare il perm dal suo indice in ogni thread piuttosto che generare tutti i permanenti e dividendoli tra i thread.