[python] Python 스크립트가 실행 중인지 확인하십시오.

웹 앱의 일부로 파이썬 데몬을 실행하고 있습니다 / 데몬이 실행 중인지 (파이썬 사용) 빠르게 확인하고 그렇지 않은 경우 시작하려면 어떻게해야합니까?

데몬의 크래시를 수정하기 위해 그렇게하고 싶습니다. 그래서 스크립트를 수동으로 실행할 필요가 없으며, 호출되는 즉시 자동으로 실행 된 다음 계속 실행됩니다.

내 스크립트가 실행 중인지 어떻게 확인할 수 있습니까 (python 사용)?



답변

어딘가에 pidfile을 놓으십시오 (예 : / tmp). 그런 다음 파일에 PID가 있는지 확인하여 프로세스가 실행 중인지 확인할 수 있습니다. 완전히 종료 할 때 파일을 삭제하는 것을 잊지 말고 시작할 때 확인하십시오.

#/usr/bin/env python

import os
import sys

pid = str(os.getpid())
pidfile = "/tmp/mydaemon.pid"

if os.path.isfile(pidfile):
    print "%s already exists, exiting" % pidfile
    sys.exit()
file(pidfile, 'w').write(pid)
try:
    # Do some actual work here
finally:
    os.unlink(pidfile)

그런 다음 /tmp/mydaemon.pid의 내용이 기존 프로세스인지 확인하여 프로세스가 실행 중인지 확인할 수 있습니다. Monit (위에 언급 됨)이이를 수행하거나 ps의 리턴 코드를 사용하여이를 확인하는 간단한 쉘 스크립트를 작성할 수 있습니다.

ps up `cat /tmp/mydaemon.pid ` >/dev/null && echo "Running" || echo "Not running"

추가 신용을 얻으려면 atexit 모듈을 사용하여 프로그램이 어떤 상황 (죽었을 때, 예외 발생 등)에서도 pidfile을 정리하도록 할 수 있습니다.


답변

Linux 시스템에서 편리한 기술은 도메인 소켓을 사용하는 것입니다.

import socket
import sys
import time

def get_lock(process_name):
    # Without holding a reference to our socket somewhere it gets garbage
    # collected when the function exits
    get_lock._lock_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)

    try:
        # The null byte (\0) means the the socket is created 
        # in the abstract namespace instead of being created 
        # on the file system itself.
        # Works only in Linux
        get_lock._lock_socket.bind('\0' + process_name)
        print 'I got the lock'
    except socket.error:
        print 'lock exists'
        sys.exit()


get_lock('running_test')
while True:
    time.sleep(3)

그것은 원자 적이며 프로세스가 SIGKILL을 보내면 잠금 파일이 주변에 놓이는 문제를 피합니다.

당신은 수 의 문서를 읽어socket.close 쓰레기 수집 때 소켓이 자동으로 닫힙니다.


답변

PID 라이브러리는 정확히이 작업을 수행 할 수 있습니다.

from pid import PidFile

with PidFile():
  do_something()

또한 pidfile이 존재하지만 프로세스가 실행되지 않는 경우를 자동으로 처리합니다.


답변

물론 Dan의 예는 제대로 작동하지 않습니다.

실제로 스크립트가 충돌하거나 예외가 발생하거나 pid 파일을 정리하지 않으면 스크립트가 여러 번 실행됩니다.

다른 웹 사이트에서 다음을 제안합니다.

잠금 파일이 이미 존재하는지 확인하는 것입니다.

\#/usr/bin/env python
import os
import sys
if os.access(os.path.expanduser("~/.lockfile.vestibular.lock"), os.F_OK):
        #if the lockfile is already there then check the PID number
        #in the lock file
        pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "r")
        pidfile.seek(0)
        old_pid = pidfile.readline()
        # Now we check the PID from lock file matches to the current
        # process PID
        if os.path.exists("/proc/%s" % old_pid):
                print "You already have an instance of the program running"
                print "It is running as process %s," % old_pid
                sys.exit(1)
        else:
                print "File is there but the program is not running"
                print "Removing lock file for the: %s as it can be there because of the program last time it was run" % old_pid
                os.remove(os.path.expanduser("~/.lockfile.vestibular.lock"))

이것은 잠금 파일에 PID 파일을 넣는 코드의 일부입니다.

pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "w")
pidfile.write("%s" % os.getpid())
pidfile.close()

이 코드는 기존 실행 프로세스와 비교하여 pid 값을 확인하여 이중 실행을 방지합니다.

도움이 되길 바랍니다.


답변

UNIX에서 프로세스를 다시 시작하기위한 아주 좋은 패키지가 있습니다. 빌드 및 구성에 대한 훌륭한 튜토리얼이있는 것은 monit 입니다. 약간의 조정으로 데몬을 유지하는 견고한 입증 된 기술을 가질 수 있습니다.


답변

내 해결책은 Windows 및 우분투 Linux에서 테스트 된 프로세스 및 명령 줄 인수를 확인하는 것입니다.

import psutil
import os

def is_running(script):
    for q in psutil.process_iter():
        if q.name().startswith('python'):
            if len(q.cmdline())>1 and script in q.cmdline()[1] and q.pid !=os.getpid():
                print("'{}' Process is already running".format(script))
                return True

    return False


if not is_running("test.py"):
    n = input("What is Your Name? ")
    print ("Hello " + n)


답변

무수히 많은 옵션이 있습니다. 한 가지 방법은 이러한 호출을 수행하는 시스템 호출 또는 Python 라이브러리를 사용하는 것입니다. 다른 하나는 다음과 같은 프로세스를 생성하는 것입니다.

ps ax | grep processName

출력을 구문 분석하십시오. 많은 사람들이이 접근 방식을 선택하지만 제 생각에는 반드시 나쁜 접근 방식은 아닙니다.