다음 시나리오를 고려해보세요. Python 서비스 프로그램을 작성하고 명령줄에서 시작합니다. 명령줄 세션은 터미널에 의해 제어되며 Python 서비스는 터미널 프로그램의 하위 프로세스가 됩니다. 따라서 터미널을 닫으면 명령줄 프로그램도 닫힙니다.
파이썬 서비스를 터미널의 영향을 받지 않고 시스템에서 영구적으로 만들려면 이를 데몬 프로세스로 전환해야 합니다.
데몬 프로세스는 시스템 백그라운드에서 실행되는 프로그램인 데몬 프로그램으로, 제어 터미널과 독립적이며 일부 주기적 작업을 수행하거나 이벤트를 트리거합니다. 일반적으로 문자 "d"를 따서 명명됩니다. 일반적인 httpd, syslogd, systemd 및 dockerd 등
Python은 매우 간단하게 데몬 프로세스를 구현할 수 있습니다. 코드와 해당 설명은 다음과 같습니다. 이 코드는 내 로컬 컴퓨터의 데몬 프로세스(자체 제작 알람시계)에서 안정적으로 실행되며, 당분간은 문제가 발생하지 않습니다.
# coding=utf8 import os import sys import atexit def daemonize(pid_file=None): """ 创建守护进程 :param pid_file: 保存进程id的文件 :return: """ # 从父进程fork一个子进程出来 pid = os.fork() # 子进程的pid一定为0,父进程大于0 if pid: # 退出父进程,sys.exit()方法比os._exit()方法会多执行一些刷新缓冲工作 sys.exit(0) # 子进程默认继承父进程的工作目录,最好是变更到根目录,否则回影响文件系统的卸载 os.chdir('/') # 子进程默认继承父进程的umask(文件权限掩码),重设为0(完全控制),以免影响程序读写文件 os.umask(0) # 让子进程成为新的会话组长和进程组长 os.setsid() # 注意了,这里是第2次fork,也就是子进程的子进程,我们把它叫为孙子进程 _pid = os.fork() if _pid: # 退出子进程 sys.exit(0) # 此时,孙子进程已经是守护进程了,接下来重定向标准输入、输出、错误的描述符(是重定向而不是关闭, 这样可以避免程序在 print 的时候出错) # 刷新缓冲区先,小心使得万年船 sys.stdout.flush() sys.stderr.flush() # dup2函数原子化地关闭和复制文件描述符,重定向到/dev/nul,即丢弃所有输入输出 with open('/dev/null') as read_null, open('/dev/null', 'w') as write_null: os.dup2(read_null.fileno(), sys.stdin.fileno()) os.dup2(write_null.fileno(), sys.stdout.fileno()) os.dup2(write_null.fileno(), sys.stderr.fileno()) # 写入pid文件 if pid_file: with open(pid_file, 'w+') as f: f.write(str(os.getpid())) # 注册退出函数,进程异常退出时移除pid文件 atexit.register(os.remove, pid_file)
데몬 프로세스 작성 단계를 요약합니다.
1. 하위 프로세스를 포크하고 상위 프로세스를 종료합니다.
2 하위 프로세스는 작업 디렉터리(chdir), 파일 권한 마스크(umask), 프로세스 그룹 및 세션 그룹(setsid)
3. 손자 프로세스는 손자 프로세스를 포크하고 자식 프로세스를 종료합니다.
4. 손자 프로세스는 버퍼를 새로 고치고 표준 입력/출력/오류를 리디렉션합니다(일반적으로 폐기를 의미함). )
5. 파일에 쓰기 위한 pid(선택 가능)
첫 번째 포크는 터미널 제어의 클러치에서 벗어나기 위한 것입니다. 상위 프로세스가 종료되는 이유는 터미널이 닫힐 때 키보드를 누르거나 신호를 보내고 상위 프로세스가 종료된 후 포크된 하위 프로세스가 고아 프로세스가 되어 init 프로세스에 의해 인수되기 때문입니다. 운영 체제이므로 터미널 제어권을 벗어납니다.
그래서 사실 두 번째 포크는 필요하지 않습니다(많은 오픈 소스 프로젝트의 코드는 두 번 포크되지 않습니다). 프로세스가 제어 터미널을 다시 열지 못하도록 주의하는 것뿐입니다. 이제 자식 프로세스가 세션 리더(세션의 첫 번째 프로세스)이고 제어 터미널을 열 수 있는 능력이 있기 때문에 다시 분기하면 손자 프로세스는 제어 터미널을 열 수 없습니다.
Linux는 "모든 것이 파일입니다"입니다. 파일 설명자는 열린 파일에 대해 커널이 생성한 인덱스이며 일반적으로 음수가 아닌 정수입니다. 프로세스는 파일 설명자를 통해 IO 작업을 수행합니다.
각 프로세스에는 자체 파일 설명자 테이블이 있으므로 동일한 설명자가 동일한 파일을 가리킬 수도 있고 다른 프로세스의 다른 설명자가 동일한 파일을 가리킬 수도 있습니다.
기본적으로 0은 표준 입력, 1은 표준 출력, 2는 표준 오류를 나타냅니다.
우리는 Linux에서 모든 파일에 읽기, 쓰기, 실행이라는 세 가지 권한이 있다는 것을 알고 있습니다. 그 중 읽기 권한은 숫자 4로 표시되며, 쓰기 권한은 2, 실행 권한은 1로 표시됩니다. ls -l 명령으로 파일 권한을 확인할 수 있으며, r/w/x는 각각 읽기/쓰기/실행 권한이 있음을 의미합니다.
모든 파일에는 사용자, 그룹, 기타의 세 가지 ID 권한도 있습니다. 일반적으로 3개의 숫자는 파일 권한을 나타내는 데 사용됩니다. 예를 들어 754:
7은 사용자 권한, 즉 파일 소유자의 권한입니다.
5는 그룹 권한, 즉 구성원의 권한입니다. 소유자의 사용자 그룹
4, Others 권한은 다른 그룹에 있는 사용자의 권한입니다
그리고 umask는 기본 권한을 제어하고 새 파일이나 폴더가 전체 권한을 갖지 못하도록 방지하는 것입니다.
시스템의 기본값은 일반적으로 022입니다(보려면 umask 명령 사용). 이는 파일 생성을 위한 기본 권한이 644이고 폴더가 755임을 의미합니다. 패턴을 보면 알겠지만, 파일 권한과 umask의 합이 666이고(웃음), 폴더 권한과 umask의 합이 777이다.
각 프로세스는 프로세스 그룹(PG, 프로세스 그룹)에 속하며, 프로세스 그룹은 여러 프로세스를 포함할 수 있습니다.
프로세스 그룹에는 프로세스 리더(Leader)가 있고, 프로세스 리더의 ID(PID, Process ID)가 전체 프로세스 그룹의 ID(PGID, Process Groupd ID)로 사용됩니다.
터미널에 로그인하면 하나의 세션에 여러 프로세스 그룹이 포함될 수 있습니다. 세션을 생성하는 프로세스가 세션 리더입니다.
이미 세션 리더인 프로세스는 세션을 생성하기 위해 setid() 메서드를 호출할 수 없습니다. 따라서 위 코드에서 자식 프로세스는 setid()를 호출할 수 있지만, 부모 프로세스는 세션 리더이기 때문에 호출할 수 없습니다.
또한 sh(Bourne Shell)는 세션 메커니즘을 지원하지 않습니다. 세션 메커니즘에는 작업 제어(Job Control)를 지원하는 쉘이 필요하기 때문입니다.
& 기호를 사용하면 백그라운드에서 명령을 실행할 수 있습니다. 데몬 프로세스와는 다릅니다.
1. 데몬 프로세스는 터미널과 아무 관련이 없으며 init 프로세스에서 채택한 고아 프로세스이지만 백그라운드 프로세스의 상위 프로세스는 터미널에 계속 인쇄할 수 있습니다. 터미널
2. 데몬 프로세스는 터미널을 닫습니다. nohup이 추가되지 않으면 사용자가 종료할 때 백그라운드 프로세스가 중지됩니다.
3 데몬 프로세스는 세션, 프로세스 그룹을 변경합니다. 작업 디렉터리 및 파일 설명자, 백그라운드 프로세스는 상위 프로세스(셸)의
을 직접 상속합니다.즉, 데몬 프로세스는 묵묵히 열심히 일하는 전도유망한 청년이고, 백그라운드 프로세스는 아버지의 재산을 묵묵히 물려받는 부유한 2세입니다.
위 내용은 Python 데몬 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!