This is an interesting concept. in English, daemon refers to the "genie", which we often see in Disney animations. some of them will fly and some will not, I often turn around the main character of cartoons and give some advice, sometimes hitting the pillar unfortunately, sometimes... "> <LINKhref =" http://www.php100.com//statics
This is another interesting concept. in English, daemon refers to "Genie", just like what we often see in Disney animations. some of them will fly, and some will not, I often turn around the cartoon hero and give some advice in the dark. sometimes I am unlucky to hit the pillar. sometimes I want to come up with some small tricks to save the hero from the enemy. For this reason, daemon is sometimes translated as "patron saint ". Therefore, the daemon process has two translation methods in China. some translate "Genie process" and some translate "daemon process", which are frequently used.
Similar to the real daemon process, the daemon process is also used to hiding itself out of sight and silently contributing to the system. sometimes they are called "background service processes ". Daemon processes have a long life cycle. Generally, they exit from execution until the entire system is shut down. Almost all server programs, including well-known Apache and wu-FTP, are implemented in the form of a daemon process. Many common commands in Linux, such as inetd and ftpd, use the letter d at the end of daemon.
Why must the daemon process be used? In Linux, the interface for communication between each system and users is called terminal. every process starting from this terminal is attached to this terminal, this terminal is called the control terminal of these processes. when the control terminal is closed, the corresponding process is automatically closed. In this case, you can use the XTerm in X-Window to experiment with it. (each XTerm is an open Terminal.) you can run the following command to start the application: $ netscape then we close the XTerm window, and the newly started netscape window will also evaporate. However, the daemon process can break through this restriction. even if the corresponding terminal is closed, it can survive for a long time in the system. if we want a process to survive for a hundred years, without being affected by user, terminal, or other changes, you must turn this process into a daemon process.
1. Daemon process programming rules
To change your process to a daemon process, follow these steps:
1. call fork to generate a child process, and the parent process exits. All subsequent work is completed in the sub-process. In this way, we can:
1.1 if we execute the program from the command line, this may lead to the illusion that the program has been executed, and shell will go back and wait for the next command;
1.2 The new process that has just been generated through fork will not be the leader of a process Group, which provides a prerequisite for the implementation of step 1.
In this case, a very interesting phenomenon occurs: because the parent process has exited before the child process, it will cause the child process to have no parent process and become an orphan process (orphan ). Every time the system finds an orphan process, it will be automatically adopted by process 1, so that the original child process will become the child process of Process 1.
2. call the setsid system call.
This is the most important step in the process. For details about setsid, see Appendix 2. it is used to create a new session and act as the session leader ). If the calling process is the leader of a process Group, the call will fail, but this is guaranteed in step 1. Calling setsid has three functions:
2.1 let the process get rid of the control of the original session;
2.2 remove the process from the control of the original process Group;
2.3 Remove the process from the control of the original control terminal;
In short, the calling process is completely independent from the control of all other processes.
3. switch the current working directory to the root directory.
If we execute this process on a temporary file system, such as/mnt/floppy/, the current working directory of the process will be/mnt/floppy /. The file system cannot be detached (umount) during the entire process, and whether or not we are using this file system, this will cause us a lot of inconvenience. The solution is to use the chdir system call to change the current working directory to the root directory. no one wants to unload the root directory.
For more information about how to use chdir, see Appendix 1.
Of course, in this step, if there are special needs, we can also change the current working directory to another path, such as/tmp.
4. set the file permission mask to 0.
This requires that the system call umask be called. See Appendix 3. Each process inherits a file permission mask from the parent process. when a new file is created, this mask is used to set the default access permissions for the file and block some permissions, for example, the write permission of a general user. When another process uses exec to call our daemon program, because we do not know what the file permission mask of the process is, it will cause some trouble when we create a new file. Therefore, we should re-set the file permission mask. we can set it to any value we want, but generally we set it to 0, it does not block any user operations.
If your application does not involve creating new files or setting file access permissions, you can also kick off the file permission mask and skip this step.
5. close all unnecessary files.
Like the file permission mask, our new process will inherit some opened files from the parent process. These opened files may never be read or written by our daemon process, but they consume the same system resources and may cause the file system to be unable to be detached. It should be noted that the file descriptor is 0, 1, and 2 (the concept of the file descriptor will be introduced in the next chapter ), that is to say, the input, output, and error files also need to be closed. Many readers may wonder this. do we not need input or output? But the fact is that after step 1 above, our daemon process has lost contact with the control terminal, and the characters we input from the terminal cannot reach the daemon process, the daemon process output characters using conventional methods (such as printf) cannot be displayed on our terminal. Therefore, these three files have lost value and should be closed.
Use PHP to write the Gearman Worker daemon
In my previous articles, I introduced the use of Gearman. In my project, I used PHP to write a Worker that has been running all the time. If you follow the example officially recommended by Gearman, it is just a simple loop to wait for the task, there will be some problems, including: 1. how to make the code modification take effect after the code is modified; 2. how to ensure that the current task is restarted after the Worker is restarted.
To solve this problem, I have considered the following solutions:
1. after the code is modified, the Worker needs to be manually restarted (killed first and then started ). This can only solve the problem of re-loading the configuration file.
2. set in Worker. after a single task loop is completed, restart the Worker. The problem with this solution is that it consumes a lot.
3. add an exit function to the Worker. if the Worker needs to exit, the Client sends an exit call with a higher priority. This requires the cooperation of the client and is not suitable for background tasks.
4. check whether the file changes in the Worker. if the file changes, exit and restart the Worker.
5. write signal control for Worker and receive restart commands, similar to the http restart graceful command.
Finally, a Daemon can be implemented by combining the 4 and 5 methods. if the configuration file changes, it will automatically restart. if the user's kill-1 pid signal is received, it also restarts.
The code is as follows:
-
-
- Declare (ticks = 1 );
- // This case will check the config file regularly, if the config file changed, it will restart it self
- // If you want to restart the daemon gracefully, give it a HUP signal
- // By shiqiang At 2011-12-04
-
- $ Init_md5 = md5_file ('config. php ');
-
- // Register signal handler
- Pcntl_signal (SIGALRM, "signal_handler", true );
- Pcntl_signal (SIGHUP, 'signal _ handler', TRUE );
-
- $ Job_flag = FALSE;
- // Job status flag, to justify if the job has been finished
- $ Signal_flag = FALSE;
- // Signal status flag, to justify whether we have ed the kill-1 signal
-
- While (1 ){
- $ Job_flag = FALSE;
- // Job status flag
- Print "Worker start running... \ n ";
- Sleep (5 );
- Print "Worker's task done... \ n ";
- $ Flag = TRUE;
- // Job status flag
- AutoStart ($ signal_flag );
- }
-
- Function signal_handler ($ signal ){
- Global $ job_flag;
- Global $ signal_flag;
-
- Switch ($ signal ){
- Case SIGQUIT:
- Print date ('Y-m-d H: I: S', time (). "Caught Signal: SIGQUIT-No: $ signal \ n ";
- Exit (0 );
- Break;
- Case SIGSTOP:
- Print date ('Y-m-d H: I: S', time (). "Caught Signal: SIGSTOP-No: $ signal \ n ";
- Break;
- Case SIGHUP:
- Print date ('Y-m-d H: I: S', time (). "Caught Signal: SIGHUP-No: $ signal \ n ";
- If ($ flag === TRUE ){
- AutoStart (TRUE );
- } Else {
- $ Signal_flag = TRUE;
- }
- Break;
- Case SIGALRM:
- Print date ('Y-m-d H: I: S', time (). "Caught Signal: SIGALRM-No: $ signal \ n ";
- // Pcntl_exec ('/bin/LS ');
- Pcntl_alarm (5 );
- Break;
- Default:
- Break;
- }
- }
-
- Function AutoStart ($ signal = FALSE, $ filename = 'config. php '){
- Global $ init_md5;
-
- If ($ signal | md5_file ($ filename )! = $ Init_md5 ){
- Print "The config file has been changed, we are going to restart. \ n ";
- $ Pid = pcntl_fork ();
- If ($ pid =-1 ){
- Print "Fork error \ n ";
- } Else if ($ pid> 0 ){
- Print "Parent exit \ n ";
- Exit (0 );
- } Else {
- $ Init_md5 = md5_file ($ filename );
- Print "Child continue to run \ n ";
- }
- }
- }