Home > Article > Backend Development > PHP uses pcntl and libevent to implement Timer function
PHP uses pcntl and libevent to implement the Timer function. Let’s look at the example first. pcntl (PHP thread) is explained below.
<?php function newChild($func_name) { echo "enter newChild\n"; $args = func_get_args(); unset($args[0]); $pid = pcntl_fork(); if ($pid == 0) { function_exists($func_name) and exit(call_user_func_array($func_name, $args)) or exit(-1); } else if($pid == -1) { echo "Couldn't create child process"; } else { return $pid; } } (PS:^_^不错的php开发交流群:256271784,验证:csl,有兴趣的话可以加入进来一起讨论) function on_timer() { echo "timer called\n"; } /** * @param $func string, function name * @param $timeouts int, microtimes for time delay */ function timer($func, $timeouts){ echo "enter timer\n"; $base = event_base_new(); $event = event_new(); event_set($event, 0, EV_TIMEOUT, $func); event_base_set($event, $base); event_add($event, $timeouts); event_base_loop($base); } $pid = newChild("timer", "on_timer", 5000000); if ($pid > 0) { echo "master process exit\n"; }
PHP extends pcntl to implement "multi-threading" (process)
pcntl and ticks
ticks are defined through declare(ticks = n) {statement} syntax. The declare syntax currently only accepts ticks, and the meaning of ticks = n he defines An event occurs when N low-level statements are executed in the statement block specified by declare. This event can be registered through register_tick_function($function_name). The signal mechanism of pcntl is based on the ticks mechanism. Therefore, we use the pcntl family function When adding signal-related functions, you need to add the declare(ticks = n) syntax structure in front.
int pcntl_alarm(int $seconds):
$seconds will send a SIGALRM signal to the process after
$seconds seconds. Each time the pcntl_alarm method is called, the previous setting will be cancelled. clock.
void pcntl_exec(string $path[, array $args[, array $env]]):
Execute a program in the current process space.
$path: must be a binary executable file, or have valid script header information (#!/usr/local/bin/php) script file path.
$args: String parameter list (array form) to be passed to the program
$envs: Environment variables. In the form of an array (key => value form) is passed to the environment variable of the program to be executed.
int pcntl_for k (void):
Create a child process, which is different from the parent process only in PID (process number) and PPID (parent process number).
in When the parent thread executes, it returns the pid of the created child process. When the child thread executes, it returns 0. When the child process fails to be created, it returns -1 in the parent process context and triggers a php error.
To understand the fork here, you need to know: pcntl_fork creates A branch node is equivalent to a mark. After the parent process is completed, the child process will continue to execute from the mark. That is to say, the code after pcntl_fork is executed twice by the parent process and the child process respectively, and the two processes get The return values are different. Therefore, the parent and child processes can be separated to execute different codes.
int pcntl_getpriority([int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]):
Get the corresponding value of the given $pid The priority of the process, the default value obtained through getmypid() is the current process.
$pid: If not specified, the default is the current process.
$process_identifier: One of PRIO_PGRP, PRIO_USER, PRIO_PROCESS, the default is PRIO_PROCESS. Among them, PRIO_PGRP refers to getting the priority of the process group, PRIO_USER refers to getting the priority of the user process, and PRIO_PROCESS refers to getting the priority of a specific process.
Returns the priority of the process, or returns false when an error occurs. The smaller the value, the higher the priority.
bool pcntl_setpriority(int $priority[, int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]:
Set the priority of the process.
$priority: priority value, in the range of -20 to 20, default priority It is 0. The smaller the value, the higher the priority.
$pid: If not specified, it refers to the current process.
$process_identifier: The meaning is the same as pcntl_getpriority's $process_identifier.
Returns TRUE if the setting is successful, and returns FALSE if it fails.
bool pcntl_signal_dispatch(void):
Call the handler of the upcoming signal installed through pcntl_signal().
The call returns TRUE on success, false on failure.
php 5.3.3 added
bool pcntl_signal(int $signo, callback $handler[, bool $restart_syscalls = true] ):
Install a new signal processor $handler for the specified signal $signo.
The last parameter does not understand the meaning.
bool pcntl_sigprocmask(int $how, array $set[, array &$oldset]):
Increase, Delete or set the lock signal. The specific behavior depends on the $how parameter
$how: SIG_BLOCK is used to add the signal to the current lock signal, SIG_UNBLOCK is used to remove the signal from the current lock signal, SIG_SETMASK is used to use the given The signal list replaces the current lock signal.
$set: The list of signals to be added, removed or set.
$oldset: Used to return the old lock signal to the caller.
Returns TRUE on success, FALSE on failure.
int pcntl_sigtimedwait( array $set[, array &$siginfo[, int $seconds = 0[, int $nanoseconds = 0]]]):
pcntl_sigtimedwait actually does the same thing as pcntl_sigwaitinfo(), but pcntl_sigtimedwait has two more Enhanced parameters $seconds and $nanoseconds, which allow the script to have an upper limit on the dwell time instead of waiting indefinitely.
$set: a list of signals that need to be waited for
$siginfo: used to return to the caller information about the signals to be waited for , see pcntl_sigwaitinfo for information content
$seconds: Number of seconds for timeout
$nanoseconds: Number of nanoseconds for timeout
After success, pcntl_sigtimedwiat() returns the signal number
int pcntl_sigwaitinfo(array $set[, array &$siginfo]):
Hang Start the execution of the current script until a signal in $set is received. If one of the signals is about to arrive (such as being locked by pcntl_sigprocmask), then pcntl_sigwaitinfo will return immediately
$set: waiting signal list
$siginfo: used Returns to the caller the information of the signal waiting for the signal, which contains the following content:
1. All signals have the following three pieces of information:
a) signo: signal number
b) errno: error number
c) code: signal code
2. SIGCHLD signal-specific information
a) status: exit value or signal
b) utime: user time spent
c) stime: system time spent
d) pid: sending process id
e ) uid: The real user ID of the sending process
3. Information owned by SIGILL, SIGFPE, SIGSEGV, SIGBUS
a) addr: The memory location where the fault occurred
4. SIGPOLL-specific information:
a) band: band event, meaning unknown
b) process or call a signal processing function. If the child process has exited when called (commonly known as a zombie process), this function will return immediately and all system resources will be released.
$status is used to save the status information of the child process , this status information is generated by the following functions: pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig.
$options: If your system allows wait3 (most BSD-like systems), you can provide an optional options parameter, If this parameter is not provided, wait will use the system call. If the system does not allow wait3, providing this parameter will have no effect. The value of $options can be 0 or the two constants WNOHANG and WUNTRACED. The
function returns the exited child process PID, or returns -1 on error, or if WNOHANG is provided as option (system where wait3 is not available) and there is no valid child process, returns 0
Zombie process: Since the parent process is after fork, it is impossible to predict when the child process will end. Therefore, in order to leave some information to the parent process, the child process will leave a data structure called a zombie, waiting for the parent process to initiate a wait operation to collect its corpse. After the child process ends (logical end) and the parent process collects its corpse, it will After a period of time, the child process is called a zombie process. After the parent process ends, all child processes will be handed over to Init. Therefore, if the parent process ends, the zombie processes will be recycled. However, if the parent process never ends, These zombie processes will always occupy the process number. If the system process number is exhausted, it will make it impossible to start a new process. Therefore, the safe way is to collect the corpses of the child processes it spawns in the parent process.
int pcntl_waitpid(int $pid , int &$status[, int $options = 0]):
Hang the current process until the child process with the given $pid exits, or the current process receives an exit signal, or receives an ige signal to call a signal handler
If the child process corresponding to the given $pid has exited (zombie state) when calling this function, the function returns immediately and all system resources are released.
$pid: process number, less than -1 indicates that the process is waiting For any child process in the group, the process group number is the absolute value of $pid. Equal to -1 indicates waiting for any Forbidden City, consistent with the behavior of the pcntl_wait function. Equal to 0 indicates waiting for a child process in the same group as the calling process, and greater than 0 indicates a specific process.
$status: used to return the child process status from the function. The status information is generated by the following functions: pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig.
$options: has the same meaning as pcntl_wait's $options
int pcntl_ wexitstatus (int $status):
Returns the return code of an interrupted child process. This function is only useful when the pcntl_wifexited function returns TRUE. The $status parameter is the status information generated by pcntl_waitpid.
bool pcntl_wifexited(int $status):
Check Check whether the given status indicates that the child process exited normally.
bool pcntl_wifsignaled(int $status):
Check whether the given status indicates that the child process exited due to receiving a certain signal.
bool pcntl_wifstopped(int $status):
Check whether $status can indicate that the child process is currently stopped. This function is only valid when acting on $status generated when the pcntl_waitpid function uses WUNTRACED as the value of the $options parameter.
int pcntl_wstopsig(int $status):
Through analysis $status returns the signal number that caused the child process to stop. This function is only valid when pcntl_wifsignaled returns TRUE.
int pcntl_wtermsig(int $status):
Returns the signal number that caused the process to interrupt. This function is only valid when pcntl_wifsignaled returns TRUE. Effective.
For more PHP related articles on using pcntl and libevent to implement the Timer function, please pay attention to the PHP Chinese website!