Python을 이용해서 데몬 프로세스를 만들어야 했다.
찾아보니 python-daemon이라는 패키지를 이용하면 간단한 데몬 프로세스를 만들 수 있었다.
$ pip install python-daemon
python-daemon 패키지를 설치하게 되면 docutils와 lockfile도 같이 받아지게 된다.
python-daemon 패키지를 이용해서 가장 간단하게 데몬 프로세스를 만드는 방법은 다음과 같다.
import daemon
import time
from datetime import datetime
def main_program():
while True:
with open('{파일 경로}/pydaemon.txt', 'a') as f:
write_str = '[{}] pydaemon write.\n'.format(
datetime.now().isoformat(sep=' ', timespec='seconds'))
f.write(write_str)
time.sleep(5)
with daemon.DaemonContext():
main_program()
이렇게 하면 pydaemon.txt 파일에 5초마다 "pydaemon write."라는 문장을 적는 데몬 프로세스를 만들 수 있게 된다.
결과를 보면 pydaemon을 실행하여도 백그라운드에서 프로세스가 실행되기 때문에 사용자는 바로 다른 작업을 할 수 있다. ps -ef 명령어를 사용해 확인했을 때 부모 PID도 1인 것을 확인할 수 있다.
데몬 프로세스이기 때문에 모든 bash 접속을 끊어도 위 프로세스는 5초마다 파일에 문장을 작성하고 있을 것이다.
위에서 작성한 프로그램은 여러 번 실행하게 되면 실행한 수만큼 데몬 프로세스가 올라가 있게 된다.
하나의 데몬 프로세스만 올라가 있을 수 있도록 하려면 pid lock 파일을 이용하여 중복 실행을 방지할 수 있다.
import daemon
from daemon.pidfile import PIDLockFile
import time
from datetime import datetime
log_path = '{파일 경로}/pydaemon.txt'
def write_message(message):
with open(log_path, 'a') as f:
f.write('[{}] {}.\n'.format(datetime.now().isoformat(
sep=' ', timespec='seconds'), message))
def main_program():
while True:
write_message('pydaemon write.')
time.sleep(5)
pid_lock_file = PIDLockFile('{PID 파일 경로}/pydaemon.pid')
if pid_lock_file.is_locked():
write_message('pydaemon is already running')
exit(1)
context = daemon.DaemonContext(
working_directory='{작업 디렉터리 경로}',
umask=0o002,
pidfile=pid_lock_file,
)
with context:
main_program()
pid lock 파일을 이용할 경우 데몬 프로세스가 이미 실행 중일 때 pydaemon을 실행시키면 pydaemon이 이미 실행 중이라는 문구를 파일에 작성하도록 하였다.
pydaemon을 실행시킬 경우 위에서 PIDLockFile()에 지정한 경로에 프로세스의 PID가 적힌 .pid 파일이 생성되고 정상적으로 종료될 경우 해당 파일은 지워진다.
이 파일을 읽어 종료 시그널을 보내면 정상적인 종료를 시킬 수 있다.