main()
for the child thread. In * nix everything is not so, because I will talk a little about this system multiprocess. * nixoids can safely skip this part, if they already know everything.pcntl_fork
. Oddly enough, she takes no arguments. What to do?pcntl_fork
, the script starts schizophrenia: the code seems to be the same, but is executed by two parallel processes. However, if you simply insert the pcntl_fork
into the script, you will not see anything visual, except that access to resources conflicts.pcntl_fork
returns 0 to the child process and the PID of the child process to the parent. Here is the usual pcntl_fork
usage pcntl_fork
:$ pid = pcntl_fork (); if ($ pid == -1) { //mistake } elseif ($ pid) { // parent process gets here } else { // and here is a child process } // and both processes will get here
pcntl_fork
works only in CGI and CLI modes. From under the Apache - it is impossible. Is logical.// create a child process $ child_pid = pcntl_fork (); if ($ child_pid) { // exit the parent console-bound process exit; } // make the main process a child. // After that, he, too, can produce children. // The harsh life of these processes ... posix_setsid ();
while (! $ stop_server) { // TODO: doing something }
$ child_processes = array (); while (! $ stop_server) { if (! $ stop_server and (count ($ child_processes) <MAX_CHILD_PROCESSES)) { // TODO: get the task // fetch child process $ pid = pcntl_fork (); if ($ pid == -1) { // TODO: error - could not create process } elseif ($ pid) { // process created $ child_processes [$ pid] = true; } else { $ pid = getmypid (); // TODO: child process - here is the workload exit; } } else { // so as not to drive the cycle at idle sleep (SOME_DELAY); } // check if one of the children died while ($ signaled_pid = pcntl_waitpid (-1, $ status, WNOHANG)) { if ($ signaled_pid == -1) { // no children left $ child_processes = array (); break; } else { unset ($ child_processes [$ signaled_pid]); } } }
kill -SIGKILL
. This is bad. This is very bad - SIGKILL
will interrupt the processes in the middle. In addition, he can not pass information.SIGTERM
- the signal of proper completion of work.// Without this directive, PHP will not intercept signals declare (ticks = 1); // Handler function sigHandler ($ signo) { global $ stop_server; switch ($ signo) { case SIGTERM: { $ stop_server = true; break; } default: { // all other signals } } } // register handler pcntl_signal (SIGTERM, "sig_handler");
function isDaemonActive ($ pid_file) { if (is_file ($ pid_file)) { $ pid = file_get_contents ($ pid_file); // check for process if (posix_kill ($ pid, 0)) { // daemon already running return true; } else { // there is a pid file, but there is no process if (! unlink ($ pid_file)) { // I can not destroy the pid-file. mistake exit (-1); } } } return false; } if (isDaemonActive ('/ tmp / my_pid_file.pid')) { echo 'Daemon already active'; exit; }
PID
daemon should be written to the pid-file.file_put_contents ('/ tmp / my_pid_file.pid', getmypid ());
Source: https://habr.com/ru/post/40432/
All Articles