2015-09-21 8 views
7

Obserwowałem to zachowanie podczas próby utworzenia zagnieżdżonych procesów potomnych w języku Python. Oto program rodzic parent_process.py:Tworzenie procesów potomnych w procesie potomnym z niepoprawnym przetwarzaniem w języku Python

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() 

Program nadrzędny wywołuje funkcję "run" w następującym programie dziecko child_process.py:

import multiprocessing 

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

Kiedy uruchamiam program nadrzędny, nic nie zostało wydrukowane a program szybko się zakończył. Jeśli jednak przeniesiony zostanie print 'TEST!', jeden wiersz powyżej (zanim zagnieżdżone procesy podrzędne zostaną utworzone), 'TEST!' są drukowane 4 razy.

Ponieważ błędy w procesie potomnym nie będą drukowane na ekranie, wydaje się, że program ulega awarii, gdy proces potomny tworzy własne zagnieżdżone procesy potomne.

Czy ktoś może wyjaśnić, co dzieje się za sceną? Dzięki!

+0

Wiem, że istnieje limit w zagnieżdżaniu, który podnosi wyjątek jon, ale daleko ci do tego w tym przypadku. Myślę, że problem jest gdzieś indziej, być może w mechanizmie "pool" ... – CoMartel

+0

Co próbujesz poprawić tym? Nie będziesz szybszy, uruchamiając pule 'Pool' niż uruchamiając większy' Pool' – CoMartel

+0

@HarryPotfleur Intencją było, aby każdy proces potomny zarządzał własnym zbiorem procesów, aby program wyglądał czysto logicznie. Powiedzmy, że mam 16 rdzeni, wtedy procesy zagnieżdżone 4x4 mogą działać jednocześnie. Dostarczam obejście poniżej. –

Odpowiedz

4

Zgodnie z dokumentacją , procesy demoniczne nie mogą odradzać procesów potomnych.

multiprocessing.Pool wykorzystuje procesy demoniczne, aby zapewnić, że nie wyciekają po zakończeniu programu.

1

Jak powiedział noxdafox, multiprocessing.Pool wykorzystuje procesy demoniczne. Znalazłem proste obejście, który używa multiprocess.Process Zamiast:

Program nadrzędny:

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() 

Program dla dzieci (z nazwą 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() 

Wyjście jest 16 linii 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