Heim > Backend-Entwicklung > PHP-Tutorial > Was ist ein Dämon? Wie implementiert man einen Daemon in PHP?

Was ist ein Dämon? Wie implementiert man einen Daemon in PHP?

青灯夜游
Freigeben: 2023-04-10 09:18:01
nach vorne
2813 Leute haben es durchsucht

Ein Daemon ist ein spezieller Prozess, der im Hintergrund läuft und zur Ausführung bestimmter Systemaufgaben verwendet wird. Dieser Artikel führt Sie durch die Implementierung eines Daemons in PHP und stellt vor, worauf Sie bei der Programmierung achten müssen.

Was ist ein Dämon? Wie implementiert man einen Daemon in PHP?

Der PHP-Implementierungsdaemon kann über die Erweiterungen pcntl und posix implementiert werden. pcntlposix 扩展实现。

编程中需要注意的地方有:

  • 通过二次 pcntl_fork() 以及 posix_setsid 让主进程脱离终端
  • 通过 pcntl_signal() 忽略或者处理 SIGHUP 信号
  • 多进程程序需要通过二次 pcntl_fork() 或者 pcntl_signal() 忽略 SIGCHLD 信号防止子进程变成 Zombie 进程
  • 通过 umask() 设定文件权限掩码,防止继承文件权限而来的权限影响功能
  • 将运行进程的 STDIN/STDOUT/STDERR 重定向到 /dev/null 或者其他流上

如果要做的更好,还需要注意:

  • 如果通过 root 启动,运行时更换到低权限用户身份
  • 及时 chdir() 防止操作错误路径
  • 多进程程序考虑定时重启,防止内存泄露

什么是daemon

文章的主角守护进程(daemon),Wikipedia 上的定义是:

在一个多任务的电脑操作系统中,守护进程(英语:daemon,/ˈdiːmən/或/ˈdeɪmən/)是一种在后台执行的电脑程序。此类程序会被以进程的形式初始化。守护进程程序的名称通常以字母“d”结尾:例如,syslogd就是指管理系统日志的守护进程。
通常,守护进程没有任何存在的父进程(即PPID=1),且在UNIX系统进程层级中直接位于init之下。守护进程程序通常通过如下方法使自己成为守护进程:对一个子进程运行fork,然后使其父进程立即终止,使得这个子进程能在init下运行。这种方法通常被称为“脱壳”。

UNIX环境高级编程(第二版)(以下使用简称 APUE 指代) 13章有云:

守护进程也成精灵进程( daemon )是生存周期较长的一种进程。它们常常在系统自举时启动,仅在系统关闭时才终止。因为他们没有控制终端,所以说他们是在后台运行的。

这里注意到,daemon有如下特征:

  • 没有终端
  • 后台运行
  • 父进程 pid 为1

想要查看运行中的守护进程可以通过 ps -ax 或者 ps -ef 查看,其中 -x 表示会列出没有控制终端的进程。

实现关注点

二次 fork 与 setsid

fork 系统调用

fork 系统调用用于复制一个与父进程几乎完全相同的进程,新生成的子进程不同的地方在于与父进程有着不同的 pid 以及有不同的内存空间,根据代码逻辑实现,父子进程可以完成一样的工作,也可以不同。子进程会从父进程中继承比如文件描述符一类的资源。

PHP 中的 pcntl 扩展中实现了 pcntl_fork() 函数,用于在 PHP 中 fork 新的进程。

setsid 系统调用

setsid 系统调用则用于创建一个新的会话并设定进程组 id。

这里有几个概念:会话进程组

在 Linux 中,用户登录产生一个会话(Session),一个会话中包含一个或者多个进程组,一个进程组又包含多个进程。每个进程组有一个组长(Session Leader),它的 pid 就是进程组的组 id。进程组长一旦打开一个终端,这一个终端就被称为控制终端。一旦控制终端发生异常(断开、硬件错误等),会发出信号到进程组组长。

后台运行程序(如 shell 中以&结尾执行指令)在终端关闭之后也会被杀死,就是没有处理好控制终端断开时发出的SIGHUP信号,而SIGHUP

Beim Programmieren sind Folgendes zu beachten: 🎜
  • Verwenden Sie den zweiten pcntl_fork() und posix_setsid, um den Hauptprozess aus dem Terminal zu holen
  • Ignorieren oder verarbeiten Sie das SIGHUP-Signal durch pcntl_signal()
  • Mehrprozessprogramme müssen zweimal pcntl_fork() oder pcntl_signal() Ignorieren Sie das Signal SIGCHLD, um zu verhindern, dass der untergeordnete Prozess zu einem Zombie-Prozess wird.
  • Legen Sie die Dateiberechtigungsmaske über umask() , um zu verhindern, dass sich von Dateiberechtigungen geerbte Berechtigungen auf Funktionen auswirken
  • Leiten Sie STDIN/STDOUT/STDERR des laufenden Prozesses nach /dev um /null oder anderes Streaming
🎜Wenn Sie es besser machen wollen, müssen Sie auch auf Folgendes achten: 🎜
Verwandte Etiketten:
php
Quelle:juejin.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage