CentOS 7.5에서 Python MultiProcess 좀비 프로세스 문제
환경 정보
- OS : CentOS 7.5
- Language : Python 2.7.5
현상
프로그램에서 불규칙적으로 Multiprocess가 종료 되지 않고 남아 있음. kill -9 {PID} 로 Multiprocess를 종료 시키면, 종료 시점으로 새로운 프로세스가 생성되며 실행 시간은 00:00 으로 변경없이 유지됨.
문제점
Multiprocess는 Memory 자원을 반환 하지 않고 계속 점유 되는 문제 발생
코드 샘플
from multiprocessing import Pool
def processing(arge):
while True:
print arge
time.sleep(10)
if __name__ == '__main__':
while True:
try:
pool = Pool(processes=2)
results = pool.map(processing, [1,2,3,4,5,6,7,8,9])
pool.close()
pool.join()
임시 해결책
발등에 떨어진 불을 끄기 위한 임시 해결책 입니다.
특정 시간 이상 좀비 프로세스로 돌고 있을 경우 강제로 kill 하는 프로그램 작성
#!/usr/bin/python
#-*- coding: utf-8 -*-
import sys
sys.getdefaultencoding()
reload(sys)
sys.setdefaultencoding('utf-8')
sys.getdefaultencoding()
import os
import time
import datetime
import commands
import re
# python_path & name
python_path = os.path.dirname (os.path.realpath(__file__))
python_name = os.path.basename(os.path.realpath(__file__))
# sleep
#time_sleep_set = 'day' # time.sleep(day)
#time_sleep_set = 'min' # time.sleep(min)
time_sleep_set = 'sec' # time.sleep(sec)
time_sleep_int = 30
def main():
chk_kill_time = 20 #minutes
chk_proc_list = ['Process Name']
for chk_proc in chk_proc_list:
pid_list = commands.getoutput("ps -eo pid,ppid,lstart,command | grep "+ chk_proc +" | grep -v grep")
if ( pid_list != '' ):
time_chk = datetime.datetime.now() - datetime.timedelta(minutes=chk_kill_time)
for pid_time_cmd in pid_list.split('\n'):
re_dst_str = pid_time_cmd
re_pattern = r'^\s*(\d+)\s+(\d+)\s+(?:\w+)\s+(\w+)\s+(\d{1,2})\s+(\d\d):(\d\d):(\d\d)\s+(\d{4})\s+(.*)'
re_compile = re.compile( re_pattern, re.I )
re_findall = re_compile.findall(re_dst_str)
re_findlen = len( re_findall )
if( re_findlen > 0 ):
pid = re_findall[0][0]
ppid = re_findall[0][1]
time_m = re_findall[0][2]
time_d = re_findall[0][3]
time_h = re_findall[0][4]
time_i = re_findall[0][5]
time_s = re_findall[0][6]
time_y = re_findall[0][7]
cmd = re_findall[0][8]
time_j = time_y +'-'+ time_m +'-'+ time_d +' '
time_j += time_h +':'+ time_i +':'+ time_s
time_j = datetime.datetime.strptime(time_j, '%Y-%b-%d %H:%M:%S')
# if ( ppid == '1' ): continue
if ( time_j < time_chk ):
os.system( 'kill -9 '+ pid )
if __name__ == '__main__':
# while True:
main()