2015-09-21 3 views
7

Ho osservato questo comportamento durante il tentativo di creare processi figli nidificati in Python. Ecco il programma principale parent_process.py:Creazione di processi figlio all'interno di un processo secondario con il multiprocesso di Python non riuscito

import multiprocessing 
import child_process 

pool = multiprocessing.Pool(processes=4) 
for i in range(4): 
     pool.apply_async(child_process.run,()) 
pool.close() 
pool.join() 

Il programma principale chiama la funzione "run" nel seguente child_process.py programma figlio:

import multiprocessing 

def run(): 
     pool = multiprocessing.Pool(processes=4) 
     print 'TEST!' 
     pool.close() 
     pool.join() 

Quando eseguo il programma principale, nulla è stato stampato e il programma è uscito rapidamente. Tuttavia, se print 'TEST!' viene spostato sopra una riga (prima che i processi figlio nidificati vengano creati), 'TEST!' vengono stampati per 4 volte.

Poiché gli errori in un processo figlio non vengono stampati sullo schermo, questo sembra mostrare che il programma si arresta in modo anomalo quando un processo figlio crea i propri processi figlio nidificati.

Qualcuno potrebbe spiegare cosa succede dietro la scena? Grazie!

+0

So che esiste un limite di nidificazione che genera un'eccezione ione, ma tu sei lontano da esso in questo caso. Penso che il problema sia da qualche altra parte, forse nel meccanismo del "pool" ... – CoMartel

+0

Cosa stai cercando di migliorare con questo? Non sarai più veloce lanciando pool di 'Pool' che lanciando un più grande' Pool' – CoMartel

+0

@HarryPotfleur L'intenzione era di lasciare che ogni processo figlio gestisse il proprio insieme di processi, quindi il programma sembra logicamente più pulito. Supponiamo di avere 16 core, quindi i processi nidificati 4x4 possono essere eseguiti simultaneamente. Fornisco una soluzione alternativa di seguito. –

risposta

4

In base alla documentazione multiprocessing, i processi demonici non possono generare processi figli.

multiprocessing.Pool utilizza i processi demonici per assicurarsi che non perdano quando si estingue il programma.

1

Come ha detto noxdafox, multiprocessing.Pool utilizza processi demonici. Ho trovato una semplice soluzione che utilizza multiprocess.Process invece:

programma principale:

import multiprocessing 
import child_process 

processes = [None] * 4 
for i in range(4): 
    processes[i] = multiprocessing.Process(target=child_process.run, args=(i,)) 
    processes[i].start() 
for i in range(4): 
    processes[i].join() 

programma Child (con il nome child_process.py):

import multiprocessing 

def test(info): 
    print 'TEST', info[0], info[1] 

def run(proc_id): 
    pool = multiprocessing.Pool(processes=4) 
    pool.map(test, [(proc_id, i) for i in range(4)]) 
    pool.close() 
    pool.join() 

L'uscita è di 16 linee di TEST:

TEST 0 0 
TEST 0 1 
TEST 0 3 
TEST 0 2 
TEST 2 0 
TEST 2 1 
TEST 2 2 
TEST 2 3 
TEST 3 0 
TEST 3 1 
TEST 3 3 
TEST 3 2 
TEST 1 0 
TEST 1 1 
TEST 1 2 
TEST 1 3