2016-06-01 3 views
1

Я не следующий тестовый код подклассов процесса от multiprocessing:Пожалуйста, объясните это раннее завершение подпроцесса multiprocess.Process?

import multiprocessing as mp 

class TestProcess(mp.Process): 
    def __init__(self,name): 
     super().__init__() 
     self.name = name 

    def run(self): 
     while True: 
      print('{} says "I am alive"'.format(self.name)) 

if __name__ == "__main__" : 

    procs = [TestProcess(i) for i in list('ABC')] 

    try: 
     for p in procs: 
      print('starting {}'.format(p.name)) 
      p.start() 
    except KeyboardInterrupt: 
     print('caught interrupt') 
    except Exception as e: 
     print(str(e)) 
    finally: 
     for p in procs: 
      print('stopping {}'.format(p.name)) 
      p.terminate() 

по какой-то причине заканчивается рано, никогда не посылая Ctrl + с и процесс B и C не кажется, бежать:

host:~ user$ python process_example.py 
    starting A 
    starting B 
    starting C 
    A says "I am alive" 
    [... x 16 lines] 
    A says "I am alistopping A 
    stopping B 
    stopping C 

Если кто-нибудь может это объяснить, я очень благодарен.

Update

Спасибо всем за незамедлительный ответ; Я обновил к следующему:

import time 
import multiprocessing as mp 

class TestProcess(mp.Process): 
    def __init__(self,name): 
     super().__init__() 
     self.name = name 

    def run(self): 
     while True: 
      print('{} says "I am alive"'.format(self.name)) 
      time.sleep(1) 

if __name__ == "__main__" : 

    procs = [TestProcess(i) for i in list('ABC')] 

    try: 
     for p in procs : 
      print('starting {}'.format(p.name)) 
      p.start() 
     for p in procs : 
      print('joining {}'.format(p.name)) 
      p.join() 
    except KeyboardInterrupt: 
     print('caught interrupt') 
    except Exception as e: 
     print(str(e)) 
    finally: 
     for p in procs : 
      print('stopping {}'.format(p.name)) 
      p.terminate() 

Теперь я получаю:

host:~ user$ python process_example.py 
starting A 
starting B 
starting C 
A says "I am alive" 
joining A 
B says "I am alive" 
C says "I am alive" 
A says "I am alive" 
B says "I am alive" 
C says "I am alive" 
A says "I am alive" 
B says "I am alive" 
C says "I am alive" 
A says "I am alive" 
B says "I am alive" 
C says "I am alive" 
A says "I am alive" 
B says "I am alive" 
C says "I am alive" 
B says "I am alive" 
A says "I am alive" 
C says "I am alive" 
^Ccaught interrupt 
stopping A 
stopping B 
stopping C 

Таким образом, только один поток присоединения необходимо?

+3

Почему это вообще не удивительно? Вы не ждете, пока ни один из ваших процессов ничего не сделает, и ничего об этом выходе не говорит о том, что завершение A происходит раньше. – user2357112

+2

Возможно, вы пропустили точку запуска процессов или потоков. Они работают параллельно с основным потоком/процессом, поэтому ваш код продолжает двигаться вперед. Используйте '.join()', если вы хотите дождаться завершения процесса (в этом случае никогда). –

+1

Вы пытаетесь * подождать * для Ctrl-C? – user2357112

ответ

3

Мне непонятно, что вы ожидаете от этого. После запуска процессов код немедленно входит в блок finally: и явно завершает их все. Поэтому, конечно, они останавливаются.

Что касается того, почему только «А» говорит, что он жив, это может варьироваться в разных платформах (ОС). Ваш метод run() - это всего лишь «цикл занятости», который работает как можно быстрее без остановок. Процессы убивают так быстро после их запуска, что это выглядит так: на вашей платформе ОС никогда не собиралась планировать временной срез для других процессов, прежде чем вы их прекратили.

Попробуйте, например, придерживаться time.sleep(10) после цикла, который запускает процессы. Это задержит убийство процессов в течение 10 секунд, и, вероятно, достаточно времени для B и C, чтобы получить некоторую любовь ;-) от операционной системы, прежде чем они будут убиты.