Sto avendo problemi di stallo con questo pezzo di codice:deadlock Python multiprocessing.Queue su put e ottenere
def _entropy_split_parallel(data_train, answers_train, weights):
CPUS = 1 #multiprocessing.cpu_count()
NUMBER_TASKS = len(data_train[0])
processes = []
multi_list = zip(data_train, answers_train, weights)
task_queue = multiprocessing.Queue()
done_queue = multiprocessing.Queue()
for feature_index in xrange(NUMBER_TASKS):
task_queue.put(feature_index)
for i in xrange(CPUS):
process = multiprocessing.Process(target=_worker,
args=(multi_list, task_queue, done_queue))
processes.append(process)
process.start()
min_entropy = None
best_feature = None
best_split = None
for i in xrange(NUMBER_TASKS):
entropy, feature, split = done_queue.get()
if (entropy < min_entropy or min_entropy == None) and entropy != None:
best_feature = feature
best_split = split
for i in xrange(CPUS):
task_queue.put('STOP')
for process in processes:
process.join()
return best_feature, best_split
def _worker(multi_list, task_queue, done_queue):
feature_index = task_queue.get()
while feature_index != 'STOP':
result = _entropy_split3(multi_list, feature_index)
done_queue.put(result)
feature_index = task_queue.get()
Quando eseguo il mio programma, che funziona bene per diversi attraversa _entropy_split_parallel
, ma alla fine deadlock. Il processo principale sta bloccando su done_queue.get()
e il processo di lavoro sta bloccando su done_queue.put()
. Poiché la coda è sempre vuota quando ciò accade, è previsto il blocco su get
. Quello che non capisco è il motivo per cui il lavoratore sta bloccando su put
, poiché ovviamente la coda non è piena (è vuota!). Ho provato gli argomenti delle parole chiave block
e timeout
, ma ottengo lo stesso risultato.
Sto utilizzando il backport multiprocessing, poiché sono bloccato con Python 2.5.
MODIFICA: Sembra che si verifichino anche problemi di deadlock con uno degli esempi forniti con il modulo di multiprocessing. È il terzo esempio dal basso here. Il deadlock sembra solo verificarsi se chiamo il metodo di prova più volte. Ad esempio, la modifica nella parte inferiore dello script per questo:
if __name__ == '__main__':
freeze_support()
for x in xrange(1000):
test()
EDIT: So che questa è una vecchia questione, ma i test dimostra che questo non è più un problema su finestre con Python 2.7. Proverò Linux e riferirò.
Penso che tutte le code dovrebbero essere vuote quando i processi vengono uniti, quindi questo non dovrebbe essere un problema. Inoltre, il processo principale è deadlocking su put, piuttosto che join. Ho appena aggiornato Python (ero bloccato con una vecchia versione), quindi lo verificherò di nuovo. – ajduff574
@ajduff nel mio caso, il deadlock non si è verificato nel join, ma anche il put, tranne che il put era nel thread secondario. Inoltre, nel mio caso, la coda che era stata inserita era vuota. Quindi penso che valga la pena sparare (ad esempio, evitando il thread principale che unisce i thread figli) nel tuo caso. – Jeet