php有一組進程控制函數,使得php能在*nix系統中實現跟c一樣的創建子進程、使用exec函數執行程序、處理信號等功能。
謹以此句獻給超工,在web server環境中不要使用這組函數,因為會導致不可預料的結果。另,windows作為非類unix系統,沒有這些函數。
PCNTL 使用ticks來作為信號處理機制(signal handle callback mechanism),可以最小程度地降低處理異步事件時的負載。何謂ticks?Tick 是一個在代碼段中解釋器每執行 N 條低級語句就會發生的事件,這個代碼段需要通過declare來指定。
PCNTL的函數都有這么些:
信號處理
int pcntl_alarm ( int $seconds )
設置一個$seconds秒后發送SIGALRM信號的計數器
bool pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls ] )
為$signo設置一個處理該信號的回調函數
下面是一個隔5秒發送一個SIGALRM信號,並由signal_handler函數獲取,然后打印一個“Caught SIGALRM”的例子:
<?php declare(ticks = 1); function signal_handler($signal) { print "Caught SIGALRM/n"; pcntl_alarm(5); } pcntl_signal(SIGALRM, "signal_handler", true); pcntl_alarm(5); for(;;) { } ?>
<?php declare(ticks = 1); function signal_handler($signal) { print "Caught SIGALRM/n"; pcntl_alarm(5); } pcntl_signal(SIGALRM, "signal_handler", true); pcntl_alarm(5); for(;;) { } ?>
執行程序
void pcntl_exec ( string $path [, array $args [, array $envs ]] )
在當前的進程空間中執行指定程序,類似於c中的exec族函數。所謂當前空間,即載入指定程序的代碼覆蓋掉當前進程的空間,執行完該程序進程即結束。
<?php $dir = '/home/shankka/'; $cmd = 'ls'; $option = '-l'; $pathtobin = '/bin/ls'; $arg = array($cmd, $option, $dir); pcntl_exec($pathtobin, $arg); echo '123'; //不會執行到該行 ?>
<?php $dir = '/home/shankka/'; $cmd = 'ls'; $option = '-l'; $pathtobin = '/bin/ls'; $arg = array($cmd, $option, $dir); pcntl_exec($pathtobin, $arg); echo '123'; //不會執行到該行 ?>
創建進程
int pcntl_fork ( void )
為當前進程創建一個子進程
int pcntl_wait ( int &$status [, int $options ] )
阻塞當前進程,只到當前進程的一個子進程退出或者收到一個結束當前進程的信號。
int pcntl_waitpid ( int $pid , int &$status [, int $options ] )
功能同pcntl_wait,區別為waitpid為等待指定pid的子進程。當pid為-1時pcntl_waitpid與pcntl_wait一樣。
在 pcntl_wait和pcntl_waitpid兩個函數中的$status中存了子進程的狀態信息,這個參數可以用於 pcntl_wifexited、pcntl_wifstopped、pcntl_wifsignaled、pcntl_wexitstatus、 pcntl_wtermsig、pcntl_wstopsig、pcntl_waitpid這些函數。
來個例子:
<?php $pid = pcntl_fork(); if($pid) { pcntl_wait($status); $id = getmypid(); echo "parent process,pid {$id}, child pid {$pid}/n"; } else { $id = getmypid(); echo "child process,pid {$id}/n"; sleep(2); } ?>
<?php $pid = pcntl_fork(); if($pid) { pcntl_wait($status); $id = getmypid(); echo "parent process,pid {$id}, child pid {$pid}/n"; } else { $id = getmypid(); echo "child process,pid {$id}/n"; sleep(2); } ?>
子進程在輸出child process等字樣之后sleep了2秒才結束,而父進程阻塞着直到子進程退出之后才繼續運行。
進程優先級:
int pcntl_getpriority ([ int $pid [, int $process_identifier ]] )
取得進程的優先級,即nice值,默認為0,在我的測試環境的linux中(CentOS release 5.2 (Final)
),優先級為-20到19,-20為優先級最高,19為最低。(手冊中為-20到20)
bool pcntl_setpriority ( int $priority [, int $pid [, int $process_identifier ]] )
設置進程的優先級
