PCNTL函數族--PHP多進程編程 (轉)


php有一組進程控制函數,使得php能在*nix系統中實現跟c一樣的創建子進程、使用exec函數執行程序、處理信號等功能。

引用
Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.


謹以此句獻給超工,在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 ]] )
設置進程的優先級


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM