2013-11-01 2 views
2

В ящиках Windows у меня есть несколько сценариев, в которых родительский процесс запускает дочерний процесс. По разным причинам - родительский процесс может потребоваться, чтобы прервать процесс ребенка, но (и это важно) позволяют ему убирать - т.е. запустить, наконец, условие:Изящно завершить процесс дочернего Python в Windows, так что выполняются окончательные предложения

try: 
    res = bookResource() 
    doStuff(res) 
finally: 
    cleanupResource(res) 

(Эти вещи могут быть встроены в контексте как ближе - и, как правило, связаны с аппаратным блокированием/состоянием базы данных)

Проблема в том, что я не могу найти способ оповестить ребенка в Windows (как и в среде Linux), чтобы он запускал очистить перед завершением. Я думаю, что это требует, чтобы дочерний процесс каким-то образом вызывал исключение (так как Ctrl-C).

Что я пробовал:

  • os.kill
  • os.signal
  • subprocess.Popen с creationFlags и использованием ctypes.windll.kernel32.GenerateConsoleCtrlEvent(1, p.pid) Abrt сигнала. Для этого требуется сигнальная ловушка и неэлементный контур, чтобы немедленно остановить его.
  • ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, p.pid) - ctrl-c event - ничего не сделал.

У кого-нибудь есть верный способ сделать это, чтобы ребенок мог очистить?

+0

поместить текстовый файл в системе, что дети периодически проверять, чтобы увидеть, если они должны выйти .. будет быть довольно уверенным ... но, вероятно, есть лучший способ или открыть какой-то сокет-сервер для прослушивания на –

+0

, вы уже используете 'signal()' для регистрации обработчика сигнала для kill -HUP? –

+1

btw, это справа: http://stackoverflow.com/questions/5033277/how-to-achieve-desired-results-when-using-the-subprocees-popen-send-signalctrl?rq=1 почти точно что вам нужно ... –

ответ

0

Я был в состоянии получить GenerateConsoleCtrlEvent работает так:

import time 
import win32api 
import win32con 
from multiprocessing import Process 


def foo(): 
    try: 
     while True: 
      print("Child process still working...") 
      time.sleep(1) 
    except KeyboardInterrupt: 
     print "Child process: caught ctrl-c" 

if __name__ == "__main__": 
    p = Process(target=foo) 
    p.start() 
    time.sleep(2) 

    print "sending ctrl c..." 
    try: 
     win32api.GenerateConsoleCtrlEvent(win32con.CTRL_C_EVENT, 0) 
     while p.is_alive(): 
      print("Child process is still alive.") 
      time.sleep(1) 
    except KeyboardInterrupt: 
     print "Main process: caught ctrl-c" 

Выход

Child process still working... 
Child process still working... 
sending ctrl c... 
Child process is still alive. 
Child process: caught ctrl-c 
Main process: caught ctrl-c 
Смежные вопросы