2016-11-03 2 views
0

Я пытаюсь закрыть дочерний процесс (который выполняет цикл while), когда завершается родительский процесс (когда родительский процесс является чистым - выход, принудительный выход или выход из-за исключения), чтобы не сделать процесс обработки детьми процессом зомби.Выйти из цикла while, когда родительский процесс завершен?

Я делаю игру, которая общается с Arduino (используя серийный), а основной процесс запускает экземпляр ShowBase Panda3D (игровой движок, делает визуализацию и многое другое), поэтому главное не следует останавливать.
Итак, я создал подпроцесс с помощью модуля многопроцессорной так, что основной процесс является безопасным от остановки ждать последовательного ввода.

Но проблема, когда я закрыть окно Panda3D, вызовите sys.exit() или выхода из исключения, основной процесс выходит немедленно и не может присоединяться или давать ложные подпроцессы, поэтому подпроцесс становится зомби.

Я понятия не имею, как это решить. Что я должен сделать, чтобы он работал так, как я ожидал?

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
from multiprocessing import Process, Queue 
from panda3d.core import * 

class HW_support: 
    def hardware_event_handler(self, process_status): 
     self.process_alive = True 
     while self.process_alive: 
      print('Working!') 
      self.process_alive = process_status.get() 
     return 

if __name__ == '__main__': 
    from direct.showbase.ShowBase import ShowBase 
    import sys 
    class TestApp(ShowBase): 
     def __init__(self): 
      ShowBase.__init__(self) 
      self.process_status_argv = Queue() 
      self.HW_sub_process = Process(target = HW_support().hardware_event_handler, args=(self.process_status_argv,)) 
      self.HW_sub_process.start() 
      base.messenger.toggleVerbose() 
      taskMgr.add(self.task_make_alive, 'task_make_alive') 

      base.accept('escape', self.exit_taskloop) 
     def exit_taskloop(self, task=None): 
      taskMgr.stop() 

     def task_make_alive(self, task=None): 
      self.process_status_argv.put(True) 
      return task.cont 

    app = TestApp() 
    app.run() 
    #app.HW_sub_process.join() 
    app.process_status_argv.put(False) 

ответ

1

в основной программе добавьте это в верхней части (значительно ниже import multiprocessing)

if multiprocessing.current_process().name == 'MainProcess': 
    import atexit 
    atexit.register(lambda *a : os.remove("running.txt")) 
    open("running.txt","wb").close() 

в subprocces изменить while True петлю на while os.path.exists("running.txt"):

в качестве альтернативы вы можете иметь atexit месту сообщение в очереди или делать что угодно, чтобы сигнализировать подпроцессу, что он должен выйти.

+0

Это очень интересная идея ... я попробую прямо сейчас, спасибо! –

+1

Обратите внимание, что в качестве блока в верхней части я думаю, что 'if __name__ ==" __main __ "' будет работать также ... Я просто хотел, чтобы было очень ясно, что цель блока if была –

+0

Это работает! И как вы сказали, поместив его, если __name__ == «__main__» будет лучше. (ТОЛЬКО В СЛУЧАЕ) В любом случае, спасибо, брат! –

1

Несколько процессов значительно усложняют работу.

Чтобы отключить процесс HW_support, вы должны отправить сообщение через свой объект Queue, тогда родитель должен join() его (дождитесь его выхода) перед тем, как выйти из него.

Все, что могло бы заставить родительский выход неожиданно (консольное прерывание, исключение сбрасывания, sys.exit и т. Д. И т. Д.), Должно быть тщательно захвачено и управляться, чтобы вы могли полностью закрыть дочерний элемент перед выходом.

+0

Umm ... тогда это хорошая идея добавить функцию в подпроцесс, который исследует основной процесс, жив, и если он мертв, выйдите из себя? Я также рассматриваю возможность использования многопроцессорной обработки, но я даже не знаю: -P –

+2

Другой ответ предполагает использование файла для этой цели, который может работать. У старого вопроса (http://stackoverflow.com/questions/25542110/kill-child-process-if-parent-is-killed-in-python) есть несколько полезных советов, в том числе установка режима «демон», который будет заставляйте его убивать, когда родителя убивают. –

+0

О, этот путь имеет значение эксперимента. Я попробую позже, хотя решение, использующее файл, отлично работает :-) В любом случае, спасибо за ответ! –