>  기사  >  백엔드 개발  >  Python이 데몬 프로세스를 구현하는 방법의 예

Python이 데몬 프로세스를 구현하는 방법의 예

高洛峰
高洛峰원래의
2017-02-10 09:06:041302검색

데몬: 일반적으로 백그라운드 프로세스로 정의되며 어떤 터미널 세션에도 속하지 않습니다. 네트워크 서비스, 인쇄 등과 같은 많은 시스템 서비스는 데몬에 의해 구현됩니다. 다음 기사에서는 Python이 데몬 프로세스를 구현하는 방법에 대한 예를 공유합니다.

시나리오 설정:

Python 서비스 프로그램을 작성하고 명령줄에서 시작했으며 명령줄 세션은 터미널에서 Python 서비스는 터미널 프로그램의 하위 프로세스가 됩니다. 따라서 터미널을 닫으면 명령줄 프로그램도 닫힙니다.

파이썬 서비스를 터미널의 영향을 받지 않고 시스템에서 영구적으로 만들려면 이를 데몬 프로세스로 전환해야 합니다.

코드 구현

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. 하위 프로세스는 작업 디렉터리(chdir), 파일 권한 마스크(umask), 프로세스 그룹 및 세션 그룹(setsid)을 변경합니다
  2. 자식 프로세스는 손자 프로세스를 분기하고 자식 프로세스를 종료합니다
  3. 손자 프로세스는 버퍼를 새로 고치고 표준 입력/출력/오류(보통 /dev/로 리디렉션) null(삭제 의미)
  4. (선택 사항) 파일에 기록된 pid

몇 가지 핵심 사항 이해

두 번 포크하는 이유

첫 번째 포크는 터미널 제어의 클러치에서 벗어나기 위한 것입니다. 상위 프로세스가 종료되는 이유는 터미널이 닫힐 때 키보드를 누르거나 신호를 보내고 상위 프로세스가 종료된 후 포크된 하위 프로세스가 고아 프로세스가 되어 init 프로세스에 의해 인수되기 때문입니다. 운영 체제이므로 터미널 제어권을 벗어납니다.

그래서 사실 두 번째 포크는 필요하지 않습니다(많은 오픈 소스 프로젝트의 코드는 두 번 포크되지 않습니다). 프로세스가 제어 터미널을 다시 열지 못하도록 주의하는 것뿐입니다. 이제 자식 프로세스가 세션 리더(세션의 첫 번째 프로세스)이고 제어 터미널을 열 수 있는 능력이 있기 때문에 다시 분기하면 손자 프로세스는 제어 터미널을 열 수 없습니다.

파일 설명자

Linux는 "모든 것이 파일입니다"입니다. 파일 설명자는 열린 파일에 대해 커널이 생성한 인덱스이며 일반적으로 음수가 아닌 정수입니다. . 프로세스는 파일 설명자를 통해 IO 작업을 수행합니다.

기본적으로 0은 표준 입력, 1은 표준 출력, 2는 표준 오류를 나타냅니다.

umask 권한 마스크

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 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.