[파이썬] 윈도우 서비스 (죽은 파이썬 스크립트 자동으로 재시작하기) Develop Tip

처음 파이썬 스크립트를 윈도우에서 서비스로 동작시키기 위하여
했던 작업이 있는데 그것 보다는 아래와 같이 작업하는게 훨씬 낫습니다.

##########################################################################################
import win32service
import win32serviceutil
import win32api
import win32event
import subprocess
import center2snmp
import snmpagent
import time
import os
import servicemanager

##########################################################################################
class TwIntService(win32serviceutil.ServiceFramework):
#=====================================================================================
_svc_name_ = "Center2SnmpService"
_svc_display_name_ = "Center to SNMP Service"
_svc_description_ = "Center to SNMP Service by Future Systems"
#=====================================================================================
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.cronperiod = None
#=====================================================================================
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
#=====================================================================================
def subprocess_start(self):
cmds = [
'C:/python27/pythonw.exe',
   '-m',
   'center2snmp',
   "C:/python27/center2snmp.ini"
]
self.center2snmp = subprocess.Popen(cmds)
cmds = [
'C:/python27/pythonw.exe',
   '-m',
   'snmpagent',
   "C:/python27/center2snmp.ini"
]
self.snmpagent = subprocess.Popen(cmds)
#=====================================================================================
def subprocess_stop(self):
self.center2snmp.terminate()
self.snmpagent.terminate()
#=====================================================================================
def SvcDoRun(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))
self.timeout = 2000     # 2 seconds
self.subprocess_start()
while True:
# Wait for service stop signal, if I timeout, loop again
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
self.subprocess_stop()
break
##########################################################################################
def ctrlHandler(ctrlType):
return True
##########################################################################################
if __name__ == '__main__':   
win32api.SetConsoleCtrlHandler(ctrlHandler, True)
win32serviceutil.HandleCommandLine(TwIntService)


그러면 이 스크립트를 설치하기 위하여
python service.py install

과 같이 설치할 수 있습니다.

그런데 문제는 위에서와 같이 subprocess.Popen 으로 돌리는 외부 파이썬 프로그램
(위의 예제에서는 center2snmp, snmpagent 라는 두 개의 스크립트)이
갑자기 죽었을 때 그것을 재기동 시켜야 한다는 상황이 발생합니다.

윈도우에서 특정 PID가 죽었는지 동작하고 있는지 살펴보는 파이썬 코드를
구글과 버퍼 오버플로우 등에서 사펴보았습니다.

처음에는 os.kill(0) 이라는 코드와
Win32를 직접 호출하는 코드 등을 모두 보았는데,
윈도우2008 R2 서버에서 동작을 안하더군요.

결론은 아래 코드를 이용하였더니 원하는 결과가 나왔습니다.

##########################################################################################
def pid_running(pid):
ps = subprocess.Popen(r'tasklist.exe /NH /FI "PID eq %d"' % (pid), shell=True, stdout=subprocess.PIPE)
output = ps.stdout.read()
ps.stdout.close()
ps.wait()
if str(pid) in output:
return True
return False

위의 코드를 적용한 전체 코드 프레임은 다음과 같습니다.

(gist 로 코드를 넣었는데 그 내용을 이글루에서 바로 올릴 수 있는 방법이 없네요)

어느 분께는 도움이 되셨기를....

덧글

  • 호로sekee 2014/09/25 15:47 # 삭제 답글

    sl4a 안드로이드에서 파이썬 스크립트를 사용하고싶은데요.. subprocess 나 os.system같은걸로 같은경로의 파일을 실행하려고 하니까 퍼미션 오류가 나네요..
    도와주세여..ㅠ.ㅠ 토렌트파일을 받았는데 실행을 못하네요...
댓글 입력 영역

구글애드텍스트