search
HomeBackend DevelopmentPHP TutorialWhat is a daemon? How to implement daemon in PHP?

A daemon is a special process that runs in the background and is used to perform specific system tasks. This article will take you through how to implement daemon in PHP and introduce what you need to pay attention to in programming.

What is a daemon? How to implement daemon in PHP?

PHP implementation daemon can be implemented through the pcntl and posix extensions.

Things that need to be noted in programming are:

  • Let the main process leave the terminal through the second pcntl_fork() and posix_setsid
  • #Pass
  • pcntl_signal() Ignore or handle SIGHUP signal
  • Multi-process programs need to pass twice
  • pcntl_fork() or pcntl_signal() Ignore the SIGCHLD signal to prevent the child process from becoming a Zombie process
  • Set the file permission mask through
  • umask() to prevent inheritance of file permissions The resulting permission impact function
  • redirects the
  • STDIN/STDOUT/STDERR of the running process to /dev/null or other streams
If you want to do better, you also need to pay attention to:

    If you start through root, change to a low-privilege user identity when running
  • Timely
  • chdir() Prevent operation error paths
  • Consider restarting multi-process programs regularly to prevent memory leaks

What is a daemon

The protagonist of the article

Daemon, the definition on Wikipedia is:

In a multi-tasking computer operating system, the daemon process (English: daemon, /ˈdiːmən/ or /ˈdeɪmən/) is a computer program that executes in the background. Such programs will be initialized as processes. The names of daemon programs usually end with the letter "d": for example, syslogd refers to the daemon that manages system logs.

Usually, the daemon process does not have any existing parent process (that is, PPID=1), and is directly under init in the UNIX system process hierarchy. A daemon program usually makes itself a daemon by running fork on a child process, and then terminating its parent process immediately so that the child process can run under init. This method is often called "shelling."

Advanced Programming in UNIX Environment (Second Edition) (hereinafter referred to as APUE) There is a cloud in Chapter 13:

Daemon processes have also become The daemon process is a process with a long life cycle. They are often started when the system boots and terminate only when the system is shut down. Because they don't have a controlling terminal, they are said to run in the background.

It is noted here that daemon has the following characteristics:

    No terminal
  • Running in the background
  • The parent process pid is 1
If you want to view the running daemon process, you can view it through

ps -ax or ps -ef, where -x means it will be listed There is no process controlling the terminal.

Implementation concerns

Second fork and setsid

fork system call

fork The system call is used to copy a process that is almost identical to the parent process. The difference between the newly generated child process and the parent process is that it has a different pid and a different According to the code logic implementation of the memory space, the parent and child processes can complete the same work or different tasks. The child process inherits resources such as file descriptors from the parent process.

The

pcntl extension in PHP implements the pcntl_fork() function, which is used to fork a new process in PHP.

setsid system call

setsid The system call is used to create a new session and set the process group id.

There are several concepts here:

Session, Process Group.

In Linux, user login generates a session. A session contains one or more process groups, and a process group contains multiple processes. Each process group has a session leader, and its pid is the group id of the process group. Once the process leader opens a terminal, this terminal is called the controlling terminal. Once an exception occurs in the control terminal (disconnection, hardware error, etc.), a signal will be sent to the process group leader.

Background running programs (such as shell execution instructions ending with

&) will also be killed after the terminal is closed, that is, the SIGHUP issued when the control terminal is disconnected is not handled properly. signal, and the default behavior of SIGHUP signal for a process is to exit the process.

Callsetsid After the system call, the current process will create a new process group. If the terminal is not opened in the current process, then there will be no control terminal in this process group, and there will be no control terminal. There will be a problem of killing the process by closing the terminal.

The posix extension in PHP implements the posix_setsid() function, which is used to set a new process group in PHP.

Orphan process

The parent process exits before the child process, and the child process will become an orphan process.

The init process will adopt the orphan process, that is, the ppid of the orphan process becomes 1.

The role of secondary fork

First of all, the setsid system call cannot be called by the process group leader and will return -1.

The sample code for the second fork operation is as follows:

$pid1 = pcntl_fork();

if ($pid1 > 0) {
    exit(0);
} else if ($pid1 < 0) {
    exit("Failed to fork 1\n");
}

if (-1 == posix_setsid()) {
    exit("Failed to setsid\n");
}

$pid2 = pcntl_fork();

if ($pid2 > 0) {
    exit(0);
} else if ($pid2 < 0) {
    exit("Failed to fork 2\n");
}

Assume that we execute the application in the terminal and the process is a. The first fork will generate a child process b. If the fork is successful, Parent process a exits. b As an orphan process, it is hosted by the init process.

At this time, process b is in process group a, and process b calls posix_setsid to request the generation of a new process group. After the call is successful, the current process group becomes b.

At this time, process b has actually separated from any control terminal. Routine:

<?php

cli_set_process_title(&#39;process_a&#39;);

$pidA = pcntl_fork();

if ($pidA > 0) {
    exit(0);
} else if ($pidA < 0) {
    exit(1);
}

cli_set_process_title(&#39;process_b&#39;);

if (-1 === posix_setsid()) {
    exit(2);
}

while(true) {
    sleep(1);
}

After executing the program:

➜  ~ php56 2fork1.php
➜  ~ ps ax | grep -v grep | grep -E &#39;process_|PID&#39;
  PID TTY      STAT   TIME COMMAND
28203 ?        Ss     0:00 process_b

From the results of ps, the TTY of process_b Has it become ? , that is, there is no corresponding control terminal.

When the code reaches this point, it seems that the function has been completed. process_b has not been killed after closing the terminal, but why is there a second fork operation?

An answer on StackOverflow is well written:

The second fork(2) is there to ensure that the new process is not a session leader , so it won't be able to (accidentally) allocate a controlling terminal, since daemons are not supposed to ever have a controlling terminal.

This is to prevent the actual working process from actively associating or The control terminal is accidentally associated. The new process generated after forking again cannot apply for association with the control terminal because it is not the process group leader.

To sum up, the function of secondary fork and setsid is to generate a new process group and prevent the working process from being associated with the control terminal.

SIGHUP signal handling

The default action of a process receiving the SIGHUP signal is to terminate the process.

And SIGHUP will be issued under the following circumstances:

  • The control terminal is disconnected, and SIGHUP is sent to the process group leader
  • Process group When the group leader exits, SIGHUP will be sent to the foreground process in the process group
  • SIGHUP is often used to notify the process to reload the configuration file (mentioned in APUE, the daemon is considered unlikely to receive it because it does not have a control terminal) This is a signal, so we choose to reuse it)

Since the actual working process is not in the foreground process group, and the leader of the process group has exited and does not control the terminal, of course there will be no processing under normal circumstances. Problem, however, in order to prevent the process from exiting due to the accidental receipt of SIGHUP, and in order to follow the conventions of daemon programming, this signal should still be processed.

Zombie process processing

What is the Zombie process

Simply put, the child process first When the parent process exits, the parent process does not call the wait system call processing, and the process becomes a Zombie process.

When the child process exits before the parent process, it will send the SIGCHLD signal to the parent process. If the parent process does not handle it, the child process will also become a Zombie process.

Zombie processes will occupy the number of processes that can be forked. Too many zombie processes will result in the inability to fork new processes.

In addition, in the Linux system, a process whose ppid is the init process will be recycled and managed by the init process after it becomes a Zombie.

Zombie process processing

From the characteristics of the Zombie process, for multi-process daemons, this problem can be solved in two ways:

  • Parent process processing SIGCHLD Signal
  • Let the child process be taken over by init

Parent process processing signal Needless to say, register the signal processing callback function and call Recycling method is enough.

For the child process to be taken over by init, you can use the method of fork twice, so that the child process a from the first fork can then fork out the actual working process b, and let a exit first, so that b becomes Orphan process so that it can be hosted by the init process.

umask

umask will be inherited from the parent process, affecting the permissions to create files.

PHP Manual mentioned:

umask() sets PHP's umask to mask & 0777 and returns the original umask. When PHP is used as a server module, the umask is restored after each request.

If the umask of the parent process is not set properly, unexpected effects will occur when performing some file operations:

➜  ~ cat test_umask.php
<?php
        chdir(&#39;/tmp&#39;);
        umask(0066);
        mkdir(&#39;test_umask&#39;, 0777);
➜  ~ php test_umask.php
➜  ~ ll /tmp | grep umask
drwx--x--x 2 root root 4.0K 8月  22 17:35 test_umask

所以,为了保证每一次都能按照预期的权限操作文件,需要置0 umask 值。

重定向0/1/2

这里的0/1/2分别指的是 STDIN/STDOUT/STDERR,即标准输入/输出/错误三个流。

样例

首先来看一个样例:

上述代码几乎完成了文章最开始部分提及的各个方面,唯一不同的是没有对标准流做处理。通过 php not_redirect_std_stream_daemon.php 指令也能让程序在后台进行。

sleep 的间隙,关闭终端,会发现进程退出。

通过 strace 观察系统调用的情况:

➜  ~ strace -p 6723
Process 6723 attached - interrupt to quit
restart_syscall(<... resuming interrupted call ...>) = 0
write(1, "1503417004\n", 11)            = 11
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({10, 0}, 0x7fff71a30ec0)      = 0
write(1, "1503417014\n", 11)            = -1 EIO (Input/output error)
close(2)                                = 0
close(1)                                = 0
munmap(0x7f35abf59000, 4096)            = 0
close(0)                                = 0

发现发生了 EIO 错误,导致进程退出。

原因很简单,即我们编写的 daemon 程序使用了当时启动时终端提供的标准流,当终端关闭时,标准流变得不可读不可写,一旦尝试读写,会导致进程退出。

信海龙的博文《一个echo引起的进程崩溃》中也提到过类似的问题。

解决方案

APUE 样例

APUE 13.3中提到过一条编程规则(第6条):

某些守护进程打开 /dev/null 时期具有文件描述符0、1和2,这样,任何一个视图读标准输入、写标准输出或者标准错误的库例程都不会产生任何效果。因为守护进程并不与终端设备相关联,所以不能在终端设备上显示器输出,也无从从交互式用户那里接受输入。及时守护进程是从交互式会话启动的,但因为守护进程是在后台运行的,所以登录会话的终止并不影响守护进程。如果其他用户在同一终端设备上登录,我们也不会在该终端上见到守护进程的输出,用户也不可期望他们在终端上的输入会由守护进程读取。

简单来说:

  • daemon 不应使用标准流
  • 0/1/2 要设定成 /dev/null

例程中使用:

for (i = 0; i < rl.rlim_max; i++)
	close(i);

fd0 = open("/dev/null", O_RDWR);
fd1 = dup(0);
fd2 = dup(0);

实现了这一个功能。dup() (参考手册)系统调用会复制输入参数中的文件描述符,并复制到最小的未分配文件描述符上。所以上述例程可以理解为:

关闭所有可以打开的文件描述符,包括标准输入输出错误;
打开/dev/null并赋值给变量fd0,因为标准输入已经关闭了,所以/dev/null会绑定到0,即标准输入;
因为最小未分配文件描述符为1,复制文件描述符0到文件描述符1,即标准输出也绑定到/dev/null;
因为最小未分配文件描述符为2,复制文件描述符0到文件描述符2,即标准错误也绑定到/dev/null;复制代码

开源项目实现:Workerman

Workerman 中的 Worker.php 中的 resetStd() 方法实现了类似的操作。

/**
* Redirect standard input and output.
*
* @throws Exception
*/
public static function resetStd()
{
   if (!self::$daemonize) {
       return;
   }
   global $STDOUT, $STDERR;
   $handle = fopen(self::$stdoutFile, "a");
   if ($handle) {
       unset($handle);
       @fclose(STDOUT);
       @fclose(STDERR);
       $STDOUT = fopen(self::$stdoutFile, "a");
       $STDERR = fopen(self::$stdoutFile, "a");
   } else {
       throw new Exception(&#39;can not open stdoutFile &#39; . self::$stdoutFile);
   }
}

Workerman 中如此实现,结合博文,可能与 PHP 的 GC 机制有关,对于 fd 0 1 2来说,PHP 会维持对这三个资源的引用计数,在直接 fclose 之后,会使得这几个 fd 对应的资源类型的变量引用计数为0,导致触发回收。所需要做的就是将这些变量变为全局变量,保证引用的存在。

推荐学习:《PHP视频教程

The above is the detailed content of What is a daemon? How to implement daemon in PHP?. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:掘金社区. If there is any infringement, please contact admin@php.cn delete
PHP's Purpose: Building Dynamic WebsitesPHP's Purpose: Building Dynamic WebsitesApr 15, 2025 am 12:18 AM

PHP is used to build dynamic websites, and its core functions include: 1. Generate dynamic content and generate web pages in real time by connecting with the database; 2. Process user interaction and form submissions, verify inputs and respond to operations; 3. Manage sessions and user authentication to provide a personalized experience; 4. Optimize performance and follow best practices to improve website efficiency and security.

PHP: Handling Databases and Server-Side LogicPHP: Handling Databases and Server-Side LogicApr 15, 2025 am 12:15 AM

PHP uses MySQLi and PDO extensions to interact in database operations and server-side logic processing, and processes server-side logic through functions such as session management. 1) Use MySQLi or PDO to connect to the database and execute SQL queries. 2) Handle HTTP requests and user status through session management and other functions. 3) Use transactions to ensure the atomicity of database operations. 4) Prevent SQL injection, use exception handling and closing connections for debugging. 5) Optimize performance through indexing and cache, write highly readable code and perform error handling.

How do you prevent SQL Injection in PHP? (Prepared statements, PDO)How do you prevent SQL Injection in PHP? (Prepared statements, PDO)Apr 15, 2025 am 12:15 AM

Using preprocessing statements and PDO in PHP can effectively prevent SQL injection attacks. 1) Use PDO to connect to the database and set the error mode. 2) Create preprocessing statements through the prepare method and pass data using placeholders and execute methods. 3) Process query results and ensure the security and performance of the code.

PHP and Python: Code Examples and ComparisonPHP and Python: Code Examples and ComparisonApr 15, 2025 am 12:07 AM

PHP and Python have their own advantages and disadvantages, and the choice depends on project needs and personal preferences. 1.PHP is suitable for rapid development and maintenance of large-scale web applications. 2. Python dominates the field of data science and machine learning.

PHP in Action: Real-World Examples and ApplicationsPHP in Action: Real-World Examples and ApplicationsApr 14, 2025 am 12:19 AM

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

PHP: Creating Interactive Web Content with EasePHP: Creating Interactive Web Content with EaseApr 14, 2025 am 12:15 AM

PHP makes it easy to create interactive web content. 1) Dynamically generate content by embedding HTML and display it in real time based on user input or database data. 2) Process form submission and generate dynamic output to ensure that htmlspecialchars is used to prevent XSS. 3) Use MySQL to create a user registration system, and use password_hash and preprocessing statements to enhance security. Mastering these techniques will improve the efficiency of web development.

PHP and Python: Comparing Two Popular Programming LanguagesPHP and Python: Comparing Two Popular Programming LanguagesApr 14, 2025 am 12:13 AM

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

The Enduring Relevance of PHP: Is It Still Alive?The Enduring Relevance of PHP: Is It Still Alive?Apr 14, 2025 am 12:12 AM

PHP is still dynamic and still occupies an important position in the field of modern programming. 1) PHP's simplicity and powerful community support make it widely used in web development; 2) Its flexibility and stability make it outstanding in handling web forms, database operations and file processing; 3) PHP is constantly evolving and optimizing, suitable for beginners and experienced developers.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor