PHP's PCNTL extension provides the function of signal processing, which allows PHP to take over the processing of signals, and signal processing is critical in the development of server-side daemon processes.
Function prototypes
bool pcntl_signal(int $signo ,callback $handler [,bool $restart_syscalls=true])
The first parameter is the signal ID
The second parameter is the PHP function of the callback when the signal occurs.
The third parameter is whether the restart is re-registered for this signal. If this parameter is false, then this signal is only registered for processing once.
The realization of pcntl_signal
<?php//信号处理需要注册ticks才能生效,这里务必注意//PHP5.4以上版本就不再依赖ticks了declare(ticks = 1);function sig_handler($signo){ switch ($signo) { case SIGUSR1: echo "SIGUSR1\n"; break; case SIGUSR2: echo "SIGUSR2\n"; break; default: echo "unknow"; break; }}//安装信号触发器器pcntl_signal(SIGUSR1, "sig_handler");pcntl_signal(SIGUSR2, "sig_handler");//向当前进程发送SIGUSR1信号posix_kill(posix_getpid(), SIGUSR1);posix_kill(posix_getpid(), SIGUSR2);?>
Executing this code will output the results you want at the terminal, in fact, the official pcntl_signal performance is very poor, mainly PHP functions can not be directly registered to the operating system signal settings, so the pcntl signal needs to rely on the tick mechanism to complete.
The principle of pcntl_signal is that the signal is first added to a queue after the signal is triggered. Then in PHP's ticks callback function constantly check whether there is a signal, if there is a signal to execute the specified callback function in PHP, if not then jump out of the function.
Ticks=1 indicates that every 1 lines of PHP code is executed to callback this function. Virtually no signal is generated for most of the time, but the ticks function is always executed.
It is good practice to remove ticks and instead use Pcntl_signal_dispatch to process the signal yourself in the code loop.
The realization of Pcntl_signal_dispatch
<?php// 定义一个处理器,接收到SIGINT信号后只输出一行信息function signalHandler($signo) { switch ($signo) { case SIGUSR1: echo "SIGUSR1\n"; break; case SIGUSR2: echo "SIGUSR2\n"; break; default: echo "unknow"; break; }}//安装信号触发器器pcntl_signal(SIGINT, ‘signalHandler‘);while (true) { sleep(1); posix_kill(posix_getpid(), SIGUSR1); pcntl_signal_dispatch(); //接收到信号时,调用注册的signalHandler()}
Combat: Use signal to handle function timeouts
<?phpfunction a(){ sleep(10); echo "OK\n";}function b(){ echo "Stop\n";}function c(){ usleep(100000);}//信号处理代码function sig(){ throw new Exception;}try{ pcntl_alarm(2); //设定超时后触发的信号 pcntl_signal(SIGALRM, "sig"); pcntl_signal_dispatch(); a(); pcntl_alarm(0);}catch(Exception $e){ echo "timeout\n";}b();a(); //等待十秒后完成b();
From for notes (Wiz)
PHP system programming--03.php process Signal processing