PHP script writes Daemon program

Source: Internet
Author: User
Tags date exit command line execution file system php script signal handler access

This is another interesting concept, daemon in English is "elf" meaning, as we often see in the Disney animation, some will fly, some will not, often around the cartoon protagonist, Shing to mention some advice, occasionally unlucky to hit the pillars, Sometimes it comes up with little tricks to save the hero from the enemy, and that's why daemon is sometimes translated as "patron saint". Therefore, the daemon process in the country also has two translation, some people translated "wizard process", some people translated "guardian process", these two types of address are very high frequency.

Similar to real daemon, the daemon process is accustomed to hiding itself out of sight, contributing silently to the system, sometimes referred to as "background service processes." The daemon process has a long lifespan, and generally, they will not exit until the entire system shuts down, starting with their execution. Almost all server programs, including our well-known Apache and WU-FTP, are implemented in the form of daemon processes. Many common Linux commands such as inetd and FTPD, the end of the letter D refers to the daemon.

Why do you have to use the daemon process? Each system in Linux communicates with the user interface called the terminal (terminal), each from this terminal to run the process will be attached to this terminal, this terminal is called the control terminal of these processes (controlling terminal), when the control terminal is closed, The corresponding process will be automatically closed. In this regard, the reader can use the xterm in X-window test, (each xterm is an open terminal,) we can type the command to start the application, such as: $netscape and then we close the Xterm window, The Netscape window, which just started, will suddenly evaporate with it. But the daemon process can break through this limitation, even if the corresponding terminal is closed, it can exist in the system for a long time, if we want to make a process of longevity, not because of user or terminal or other changes are affected, we must turn this process into a daemon process.

1. Programming rules for daemon processes

If you want to turn your process into a daemon process, we must follow these steps strictly:

1, the call Fork produces a subprocess, while the parent process exits. All of our follow-up work is done in the subprocess. In doing so we can:

1.1 If we are executing the program from the command line, this can cause the execution of the program to be completed, the shell will return to wait for the next command;

1.2 The new process that has just passed fork will not be the leader of a process group, which provides a prerequisite for the implementation of step 2nd.

This is also an interesting phenomenon: because the parent process has exited before the child process, it causes the child process to have no parent process and become an orphan process (orphan). Whenever the system discovers an orphan process, it is automatically adopted by the 1th process, so that the original subprocess becomes a subprocess of the 1th process.

2, call Setsid system call.

This is the most important step in the whole process. Setsid's introduction is shown in Appendix 2, which is to create a new session and to be the group leader (session leader). If the calling process is the leader of a process group, the call fails, but this is guaranteed in step 1th. Calling Setsid has 3 functions:

2.1 Let the process get rid of the control of the original session;

2.2 Let the process get rid of the control of the original process group;

2.3 Let the process get rid of the control of the original control terminal;

In short, the calling process is completely self-contained and detached from the control of all other processes.

3, the current working directory to switch to the root directory.

If we were to execute this process on a temporarily loaded filesystem, for example:/mnt/floppy/, the current working directory for the process would be/mnt/floppy/. The filesystem cannot be unloaded while the entire process is running (umount), and it can be a lot of inconvenience to us whether or not we are using the file system. The solution is to use the CHDIR system call to change the current working directory into a root directory, no one should want to remove the root directory.

For the use of ChDir, see Appendix 1.

Of course, in this step, if there is a special need, we can also change the current working directory to other paths, such as/tmp.

4, the file permission mask set to 0.

This requires calling the system call Umask, see Appendix 3. Each process inherits a file permission mask from the parent process, and when a new file is created, the mask is used to set the default access permissions for the file, masking certain permissions, such as Write permissions for the general user. When another process invokes the daemon program we write with exec, we do not know what the file permission mask for that process is, and this can cause some trouble when we create a new file. So, we should reset the file permission mask, we can set any value we want, but in general, everyone set it to 0, so that it does not block any user action.

If your application doesn't involve creating new files or file access permissions, you can simply kick the file permission mask off and skip this step.

5. Close all unwanted files.

As with the file permission mask, our new process inherits some open files from the parent process. These open files may never be read or written by our daemon process, but they consume the same system resources and may cause the file system in which they reside to not be unloaded. It should be noted that three files with file descriptors 0, 1, and 2 (the concept of file descriptors will be introduced in the next chapter), that is, we often say that the three files of input, output and error also need to be closed. It is likely that many readers will be surprised by this, do not we need to input the output? But the fact is that after the 2nd step of the above, our daemon process has lost contact with the control terminal that we belong to, the characters we enter from the terminal cannot reach the daemon process, daemon the process in the usual way ( such as printf) will not be able to display the characters on our terminals. So these three files have lost the value of existence and should also be closed.

using PHP to write the Gearman worker daemon

In my previous article, I introduced the use of Gearman. In my project, I used PHP to write the worker that was running all the time. If according to Gearman official recommended example, just a simple loop to wait for the task, there will be some problems, including: 1, the current code has been modified, how to make the code changes in effect; 2, restart the worker, how to ensure that the current task to deal with the success of the restart.

To address this issue, I have considered the following solutions:

1. After each modification of the code, the worker needs to manually reboot (kill and then start). This only solves the problem of reloading the configuration file.

2, in the worker set, after a single task cycle is completed, the worker to restart. The problem with this scheme is that it consumes a large proportion.

3. Add an exit function to the worker, and send a higher priority exit call on the client side if the worker exits. This requires the client to cooperate, in the use of background class tasks, not very appropriate.

4, in the worker to check whether the file changes, if a change occurred, quit and restart itself.

5, for the worker to write signal control, accept the restart instructions, similar to the HTTP restart graceful instructions.

Finally, combining 4 and 52 methods, you can implement a daemon that automatically restarts if a configuration file changes, and restarts if the user's KILL-1 PID signal is received.

The code is as follows:

  1. <?php
  2. DECLARE (ticks = 1);
  3. This case would check the config file regularly, if the config file changed, it'll restart it self
  4. If you are want to restart the daemon gracefully, give it a HUP signal
  5. by shiqiang<cocowool@gmail.com> at 2011-12-04
  6. $init _md5 = md5_file (' config.php ');
  7. Register Signal Handler
  8. Pcntl_signal (SIGALRM, "Signal_handler", true);
  9. Pcntl_signal (sighup, ' Signal_handler ', TRUE);
  10. $job _flag = FALSE;
  11. Job status flag, to justify if the job has been finished
  12. $signal _flag = FALSE;
  13. Signal status flag, to justify whether we received the KILL-1 Signal
  14. while (1) {
  15. $job _flag = FALSE;
  16. JOB Status Flag
  17. Print "Worker start running ... \ n";
  18. Sleep (5);
  19. Print "Worker ' s task done ... \ n";
  20. $flag = TRUE;
  21. JOB Status Flag
  22. AutoStart ($signal _flag);
  23. }
  24. function Signal_handler ($signal) {
  25. Global $job _flag;
  26. Global $signal _flag;
  27. Switch ($signal) {
  28. Case Sigquit:
  29. Print date (' y-m-d h:i:s ', Time ()). "Caught signal:sigquit-no: $signal \ n";
  30. Exit (0);
  31. Break
  32. Case SIGSTOP:
  33. Print date (' y-m-d h:i:s ', Time ()). "Caught signal:sigstop-no: $signal \ n";
  34. Break
  35. Case SIGHUP:
  36. Print date (' y-m-d h:i:s ', Time ()). "Caught signal:sighup-no: $signal \ n";
  37. if ($flag = = TRUE) {
  38. AutoStart (TRUE);
  39. }else{
  40. $signal _flag = TRUE;
  41. }
  42. Break
  43. Case SIGALRM:
  44. Print date (' y-m-d h:i:s ', Time ()). "Caught signal:sigalrm-no: $signal \ n";
  45. Pcntl_exec ('/bin/ls ');
  46. Pcntl_alarm (5);
  47. Break
  48. Default
  49. Break
  50. }
  51. }
  52. function AutoStart ($signal = FALSE, $filename = ' config.php ') {
  53. Global $init _md5;
  54. if ($signal md5_file ($filename)!= $init _md5) {
  55. Print "The config file has been changed, we are going to restart. \ n ";
  56. $pid = Pcntl_fork ();
  57. if ($pid = = 1) {
  58. print "Fork error \ n";
  59. }else if ($pid > 0) {
  60. print "Parent exit \ n";
  61. Exit (0);
  62. }else{
  63. $init _md5 = Md5_file ($filename);
  64. Print "Child continue to run \ n";
  65. }
  66. }
  67. }


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.