2014-09-26 3 views
6

Я хочу остановить все потоки от одного рабочего.Как убить всех работников бассейна в многопроцессе?

У меня есть пул потоков с 10 рабочими:

def myfunction(i): 
    print(i) 
    if (i == 20): 
     sys.exit() 

p = multiprocessing.Pool(10, init_worker) 

for i in range(100): 
    p.apply_async(myfunction, (i,)) 

Моя программа не останавливается и другие процессы продолжают работать, пока все 100 итераций не будут завершены. Я хочу полностью остановить пул изнутри потока, который вызывает sys.exit(). То, как оно написано в настоящее время, остановит только рабочего, который вызывает sys.exit().

ответ

11

Это не работает так, как вы намереваетесь, потому что вызов sys.exit() в рабочем процессе прекращает работу только работника. Это не влияет на родительский процесс или других работников, поскольку они являются отдельными процессами, а повышение SystemExit влияет только на текущий процесс. Вам нужно отправить сигнал назад родительскому процессу, чтобы сообщить ему, что он должен отключиться. Один из способов сделать это для вашего потребительных случае будут использовать Event созданные в multiprocessing.Manager сервере:

import multiprocessing 

def myfunction(i, event): 
    if not event.is_set(): 
     print i 
    if i == 20: 
     event.set() 

if __name__ == "__main__": 
    p= multiprocessing.Pool(10) 
    m = multiprocessing.Manager() 
    event = m.Event() 
    for i in range(100): 
     p.apply_async(myfunction , (i, event)) 
    p.close() 

    event.wait() # We'll block here until a worker calls `event.set()` 
    p.terminate() # Terminate all processes in the Pool 

Выход:

0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 

Как указано в ответе от Луки, есть гонки здесь : Нет никакой гарантии, что все рабочие будут работать в порядке, поэтому возможно, что myfunction(20, ..) будет работать до myfuntion(19, ..), например. Также возможно, что другие работники после 20 будут работать до того, как основной процесс сможет действовать на установленное событие. Я уменьшил размер окна гонки, добавив if not event.is_set(): звонок до печати i, но он все еще существует.

+1

большое спасибо +1 – N3TC4t

+0

Что такое переменный пул в приведенном выше коде? –

+0

@RajanChaudan Опечатка! Я исправил это сейчас. – dano

1

Вы не можете этого сделать.

Даже если вы смогли завершить все свои процессы, когда i == 20, вы не можете быть уверены, что напечатано только 20 номеров, потому что ваши процессы будут выполняться в недетерминированном порядке.

Если вы хотите запускать только 20 процессов, вам необходимо управлять им из вашего основного процесса (т. Е. Вашего контура управления).

Смежные вопросы