国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

php daemon

May 28, 2018 pm 03:49 PM
php process

The content shared with you in this article is about the php daemon process (Daemon). It has certain reference value. Friends in need can refer to it.

The daemon process (Daemon) is a process that runs in the background. a special process. It is independent of the control terminal and periodically performs some task or waits for some event to occur. Daemon is a very useful process. PHP can also implement the function of daemon process.

1. Basic concepts

Process

Each process has a parent process. When the child process exits, the parent process can get the information that the child process exits. state.

Process Group

Each process belongs to a process group. Each process group has a process group number, which is equal to the PID of the process group leader

2. Key points of daemon programming

1. Run in the background.?
? To avoid hanging the control terminal, put Daemon into the background for execution. The method is to call fork in the process to terminate the parent process and let Daemon execute in the background in the child process. if($pid=pcntl_fork()) exit(0);//It is the parent process, end the parent process, and the child process continues
2. Leave the control terminal, log in to the session and process group
It is necessary to introduce Linux first The relationship between the process and the control terminal, the login session and the process group: the process belongs to a process group, and the process group number (GID) is the process number (PID) of the process group leader. A login session can contain multiple process groups. These process groups share a controlling terminal. This control terminal is usually the login terminal where the process was created. Controlling terminals, login sessions, and process groups are usually inherited from the parent process. Our purpose is to get rid of them and not be affected by them. The method is to call setsid() to make the process the session leader based on point 1: posix_setsid();
Description: The setsid() call fails when the process is the session leader. But the first point already ensures that the process is not the session leader. After the setsid() call is successful, the process becomes the new session group leader and new process group leader, and is separated from the original login session and process group. Due to the exclusivity of the session process to the control terminal, the process is detached from the control terminal at the same time.
3. Disable the process from reopening the control terminal
Now, the process has become the session leader without a terminal. But it can be re-applied to open a control terminal. You can prevent the process from reopening the control terminal by making the process no longer the session leader: if($pid=pcntl_fork()) exit(0);//End the first child process, the second child process Continue (the second child process is no longer the session leader)
4. Close the open file descriptor
The process inherits the open file descriptor from the parent process that created it. If it is not closed, system resources will be wasted, the file system where the process is located will not be able to be unmounted, and unpredictable errors will occur. Close them as follows:
FClose (STDIN), FClose (STDOUT), FClose (STDERR) Close Standard input Output and Error Display.
5. Change the current working directory
When a process is active, the file system where its working directory is located cannot be removed. Generally you need to change the working directory to the root directory. For the process that needs to dump the core and write the running log, change the working directory to a specific directory such as chdir("/")
6. Reset the file creation mask
The process inherits the file from the parent process that created it Create a mask. It may modify the access bits of files created by the daemon. To prevent this, clear the file creation mask: umask(0);
7. Handling the SIGCHLD signal
Handling the SIGCHLD signal is not necessary. But for some processes, especially server processes, child processes are often generated to handle requests when requests arrive. If the parent process does not wait for the child process to end, the child process will become a zombie process (zombie) and occupy system resources. If the parent process waits for the child process to end, it will increase the burden on the parent process and affect the concurrency performance of the server process. Under Linux, you can simply set the operation of the SIGCHLD signal to SIG_IGN. signal(SIGCHLD,SIG_IGN);
In this way, the kernel will not generate a zombie process when the child process ends. This is different from BSD4. Under BSD4, you must explicitly wait for the child process to end before releasing the zombie process. For questions about signals, please refer to Linux Signal description list

  1. <?php  
    /** 
    *@author tengzhaorong@gmail.com 
    *@date 2013-07-25 
    * 后臺腳本控制類 
    */  
    class DaemonCommand{  
       
        private $info_dir="/tmp";  
        private $pid_file="";  
        private $terminate=false; //是否中斷  
        private $workers_count=0;  
        private $gc_enabled=null;  
        private $workers_max=8; //最多運行8個進程  
       
        public function __construct($is_sington=false,$user=&#39;nobody&#39;,$output="/dev/null"){  
       
                $this->is_sington=$is_sington; //是否單例運行,單例運行會在tmp目錄下建立一個唯一的PID  
                $this->user=$user;//設置運行的用戶 默認情況下nobody  
                $this->output=$output; //設置輸出的地方  
                $this->checkPcntl();  
        }  
        //檢查環(huán)境是否支持pcntl支持  
        public function checkPcntl(){  
            if ( ! function_exists(&#39;pcntl_signal_dispatch&#39;)) {  
                // PHP < 5.3 uses ticks to handle signals instead of pcntl_signal_dispatch  
                // call sighandler only every 10 ticks  
                declare(ticks = 10);  
            }  
       
            // Make sure PHP has support for pcntl  
            if ( ! function_exists(&#39;pcntl_signal&#39;)) {  
                $message = &#39;PHP does not appear to be compiled with the PCNTL extension.  This is neccesary for daemonization&#39;;  
                $this->_log($message);  
                throw new Exception($message);  
            }  
            //信號處理  
            pcntl_signal(SIGTERM, array(__CLASS__, "signalHandler"),false);  
            pcntl_signal(SIGINT, array(__CLASS__, "signalHandler"),false);  
            pcntl_signal(SIGQUIT, array(__CLASS__, "signalHandler"),false);  
       
            // Enable PHP 5.3 garbage collection  
            if (function_exists(&#39;gc_enable&#39;))  
            {  
                gc_enable();  
                $this->gc_enabled = gc_enabled();  
            }  
        }  
       
        // daemon化程序  
        public function daemonize(){  
       
            global $stdin, $stdout, $stderr;  
            global $argv;  
       
            set_time_limit(0);  
       
            // 只允許在cli下面運行  
            if (php_sapi_name() != "cli"){  
                die("only run in command line mode\n");  
            }  
       
            // 只能單例運行  
            if ($this->is_sington==true){  
       
                $this->pid_file = $this->info_dir . "/" .__CLASS__ . "_" . substr(basename($argv[0]), 0, -4) . ".pid";  
                $this->checkPidfile();  
            }  
       
            umask(0); //把文件掩碼清0  
       
            if (pcntl_fork() != 0){ //是父進程,父進程退出  
                exit();  
            }  
       
            posix_setsid();//設置新會話組長,脫離終端  
       
            if (pcntl_fork() != 0){ //是第一子進程,結(jié)束第一子進程     
                exit();  
            }  
       
            chdir("/"); //改變工作目錄  
       
            $this->setUser($this->user) or die("cannot change owner");  
       
            //關閉打開的文件描述符  
            fclose(STDIN);  
            fclose(STDOUT);  
            fclose(STDERR);  
       
            $stdin  = fopen($this->output, &#39;r&#39;);  
            $stdout = fopen($this->output, &#39;a&#39;);  
            $stderr = fopen($this->output, &#39;a&#39;);  
       
            if ($this->is_sington==true){  
                $this->createPidfile();  
            }  
       
        }  
        //--檢測pid是否已經(jīng)存在  
        public function checkPidfile(){  
       
            if (!file_exists($this->pid_file)){  
                return true;  
            }  
            $pid = file_get_contents($this->pid_file);  
            $pid = intval($pid);  
            if ($pid > 0 && posix_kill($pid, 0)){  
                $this->_log("the daemon process is already started");  
            }  
            else {  
                $this->_log("the daemon proces end abnormally, please check pidfile " . $this->pid_file);  
            }  
            exit(1);  
       
        }  
        //----創(chuàng)建pid  
        public function createPidfile(){  
       
            if (!is_dir($this->info_dir)){  
                mkdir($this->info_dir);  
            }  
            $fp = fopen($this->pid_file, &#39;w&#39;) or die("cannot create pid file");  
            fwrite($fp, posix_getpid());  
            fclose($fp);  
            $this->_log("create pid file " . $this->pid_file);  
        }  
       
        //設置運行的用戶  
        public function setUser($name){  
       
            $result = false;  
            if (empty($name)){  
                return true;  
            }  
            $user = posix_getpwnam($name);  
            if ($user) {  
                $uid = $user[&#39;uid&#39;];  
                $gid = $user[&#39;gid&#39;];  
                $result = posix_setuid($uid);  
                posix_setgid($gid);  
            }  
            return $result;  
       
        }  
        //信號處理函數(shù)  
        public function signalHandler($signo){  
       
            switch($signo){  
       
                //用戶自定義信號  
                case SIGUSR1: //busy  
                if ($this->workers_count < $this->workers_max){  
                    $pid = pcntl_fork();  
                    if ($pid > 0){  
                        $this->workers_count ++;  
                    }  
                }  
                break;  
                //子進程結(jié)束信號  
                case SIGCHLD:  
                    while(($pid=pcntl_waitpid(-1, $status, WNOHANG)) > 0){  
                        $this->workers_count --;  
                    }  
                break;  
                //中斷進程  
                case SIGTERM:  
                case SIGHUP:  
                case SIGQUIT:  
       
                    $this->terminate = true;  
                break;  
                default:  
                return false;  
            }  
       
        }  
        /** 
        *開始開啟進程 
        *$count 準備開啟的進程數(shù) 
        */  
        public function start($count=1){  
       
            $this->_log("daemon process is running now");  
            pcntl_signal(SIGCHLD, array(__CLASS__, "signalHandler"),false); // if worker die, minus children num  
            while (true) {  
                if (function_exists(&#39;pcntl_signal_dispatch&#39;)){  
       
                    pcntl_signal_dispatch();  
                }  
       
                if ($this->terminate){  
                    break;  
                }  
                $pid=-1;  
                if($this->workers_count<$count){  
       
                    $pid=pcntl_fork();  
                }  
       
                if($pid>0){  
       
                    $this->workers_count++;  
       
                }elseif($pid==0){  
       
                    // 這個符號表示恢復系統(tǒng)對信號的默認處理  
                    pcntl_signal(SIGTERM, SIG_DFL);  
                    pcntl_signal(SIGCHLD, SIG_DFL);  
                    if(!empty($this->jobs)){  
                        while($this->jobs[&#39;runtime&#39;]){  
                            if(empty($this->jobs[&#39;argv&#39;])){  
                                call_user_func($this->jobs[&#39;function&#39;],$this->jobs[&#39;argv&#39;]);  
                            }else{  
                                call_user_func($this->jobs[&#39;function&#39;]);  
                            }  
                            $this->jobs[&#39;runtime&#39;]--;  
                            sleep(2);  
                        }  
                        exit();  
       
                    }  
                    return;  
       
                }else{  
       
                    sleep(2);  
                }  
       
       
            }  
       
            $this->mainQuit();  
            exit(0);  
       
        }  
       
        //整個進程退出  
        public function mainQuit(){  
       
            if (file_exists($this->pid_file)){  
                unlink($this->pid_file);  
                $this->_log("delete pid file " . $this->pid_file);  
            }  
            $this->_log("daemon process exit now");  
            posix_kill(0, SIGKILL);  
            exit(0);  
        }  
       
        // 添加工作實例,目前只支持單個job工作  
        public function setJobs($jobs=array()){  
       
            if(!isset($jobs[&#39;argv&#39;])||empty($jobs[&#39;argv&#39;])){  
       
                $jobs[&#39;argv&#39;]="";  
       
            }  
            if(!isset($jobs[&#39;runtime&#39;])||empty($jobs[&#39;runtime&#39;])){  
       
                $jobs[&#39;runtime&#39;]=1;  
       
            }  
       
            if(!isset($jobs[&#39;function&#39;])||empty($jobs[&#39;function&#39;])){  
       
                $this->log("你必須添加運行的函數(shù)!");  
            }  
       
            $this->jobs=$jobs;  
       
        }  
        //日志處理  
        private  function _log($message){  
            printf("%s\t%d\t%d\t%s\n", date("c"), posix_getpid(), posix_getppid(), $message);  
        }  
       
    }  
       
    //調(diào)用方法1  
    $daemon=new DaemonCommand(true);  
    $daemon->daemonize();  
    $daemon->start(2);//開啟2個子進程工作  
    work();  
       
       
       
       
    //調(diào)用方法2  
    $daemon=new DaemonCommand(true);  
    $daemon->daemonize();  
    $daemon->addJobs(array(&#39;function&#39;=>&#39;work&#39;,&#39;argv&#39;=>&#39;&#39;,&#39;runtime&#39;=>1000));//function 要運行的函數(shù),argv運行函數(shù)的參數(shù),runtime運行的次數(shù)  
    $daemon->start(2);//開啟2個子進程工作  
       
    //具體功能的實現(xiàn)  
    function work(){  
          echo "測試1";  
    }  
    ?>

Related recommendations:

Detailed explanation of PHP inter-process communication

Summary about points to note about PHP process communication


The above is the detailed content of php daemon. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

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.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to get the current session ID in PHP? How to get the current session ID in PHP? Jul 13, 2025 am 03:02 AM

The method to get the current session ID in PHP is to use the session_id() function, but you must call session_start() to successfully obtain it. 1. Call session_start() to start the session; 2. Use session_id() to read the session ID and output a string similar to abc123def456ghi789; 3. If the return is empty, check whether session_start() is missing, whether the user accesses for the first time, or whether the session is destroyed; 4. The session ID can be used for logging, security verification and cross-request communication, but security needs to be paid attention to. Make sure that the session is correctly enabled and the ID can be obtained successfully.

PHP get substring from a string PHP get substring from a string Jul 13, 2025 am 02:59 AM

To extract substrings from PHP strings, you can use the substr() function, which is syntax substr(string$string,int$start,?int$length=null), and if the length is not specified, it will be intercepted to the end; when processing multi-byte characters such as Chinese, you should use the mb_substr() function to avoid garbled code; if you need to intercept the string according to a specific separator, you can use exploit() or combine strpos() and substr() to implement it, such as extracting file name extensions or domain names.

How do you perform unit testing for php code? How do you perform unit testing for php code? Jul 13, 2025 am 02:54 AM

UnittestinginPHPinvolvesverifyingindividualcodeunitslikefunctionsormethodstocatchbugsearlyandensurereliablerefactoring.1)SetupPHPUnitviaComposer,createatestdirectory,andconfigureautoloadandphpunit.xml.2)Writetestcasesfollowingthearrange-act-assertpat

How to split a string into an array in PHP How to split a string into an array in PHP Jul 13, 2025 am 02:59 AM

In PHP, the most common method is to split the string into an array using the exploit() function. This function divides the string into multiple parts through the specified delimiter and returns an array. The syntax is exploit(separator, string, limit), where separator is the separator, string is the original string, and limit is an optional parameter to control the maximum number of segments. For example $str="apple,banana,orange";$arr=explode(",",$str); The result is ["apple","bana

JavaScript Data Types: Primitive vs Reference JavaScript Data Types: Primitive vs Reference Jul 13, 2025 am 02:43 AM

JavaScript data types are divided into primitive types and reference types. Primitive types include string, number, boolean, null, undefined, and symbol. The values are immutable and copies are copied when assigning values, so they do not affect each other; reference types such as objects, arrays and functions store memory addresses, and variables pointing to the same object will affect each other. Typeof and instanceof can be used to determine types, but pay attention to the historical issues of typeofnull. Understanding these two types of differences can help write more stable and reliable code.

Using std::chrono in C Using std::chrono in C Jul 15, 2025 am 01:30 AM

std::chrono is used in C to process time, including obtaining the current time, measuring execution time, operation time point and duration, and formatting analysis time. 1. Use std::chrono::system_clock::now() to obtain the current time, which can be converted into a readable string, but the system clock may not be monotonous; 2. Use std::chrono::steady_clock to measure the execution time to ensure monotony, and convert it into milliseconds, seconds and other units through duration_cast; 3. Time point (time_point) and duration (duration) can be interoperable, but attention should be paid to unit compatibility and clock epoch (epoch)

How does PHP handle Environment Variables? How does PHP handle Environment Variables? Jul 14, 2025 am 03:01 AM

ToaccessenvironmentvariablesinPHP,usegetenv()orthe$_ENVsuperglobal.1.getenv('VAR_NAME')retrievesaspecificvariable.2.$_ENV['VAR_NAME']accessesvariablesifvariables_orderinphp.iniincludes"E".SetvariablesviaCLIwithVAR=valuephpscript.php,inApach

PHP header location not working after include PHP header location not working after include Jul 13, 2025 am 02:08 AM

When encountering the problem that header('Location:...') does not work, the common reasons and solutions are as follows: 1. There is output in advance, causing the header to fail. The solution is to ensure that there is no output before the jump, including spaces, HTML or echo; 2. There is excess output or UTF-8 BOM characters in the include or require file. The file encoding should be checked and saved as "UTF-8 BOM-free"; 3. It is recommended to use ob_start() to turn on the output buffer before the jump, and cooperate with ob_end_flush() to delay the output; 4. After the jump, be sure to add exit to prevent subsequent code execution; 5. Make sure that the header() function call is before all outputs.

See all articles