ÒÔʵÀýÈ«Ãæ½²½âPHPÖжà½ø³Ì±à³ÌµÄÏà¹Øº¯ÊýµÄʹÓÃ

5年以前  |  阅读数:236 次  |  编程语言:PHP 
PHPÓÐÒ»×e½ø³Ì¿ØÖƺ¯Êý(±aÒeʱÐeÒª¨Cenable-pcntlÓeposixÀ(C)Õ¹)£¬Ê¹µÃphpÄÜʵÏÖ¸ucÒ»ÑuµÄ´´½¨×Ó½ø³Ì¡¢Ê¹ÓÃexecº¯ÊýÖ´ÐгÌÐo¡¢´¦ÀiÐźŵȹ¦ÄÜ¡£  

    <?php 
      header('content-type:text/html;charset=utf-8' ); 

      // ±ØÐe¼ÓÔØÀ(C)Õ¹ 
      if (!function_exists("pcntl_fork")) { 
        die("pcntl extention is must !"); 
      } 
      //×ܽø³ÌµÄÊýÁ¿ 
      $totals = 3; 
      // Ö´ÐеĽű¾ÊýÁ¿ 
      $cmdArr = array(); 
      // Ö´ÐеĽű¾ÊýÁ¿µÄÊý×e 
      for ($i = 0; $i < $totals; $i++) { 
        $cmdArr[] = array("path" => __DIR__ . "/run.php", 'pid' =>$i ,'total' =>$totals); 
      } 

      /* 
      Õ¹¿ª£º$cmdArr 
      Array 
      ( 
        [0] => Array 
          ( 
            [path] => /var/www/html/company/pcntl/run.php 
            [pid] => 0 
            [total] => 3 
          ) 

        [1] => Array 
          ( 
            [path] => /var/www/html/company/pcntl/run.php 
            [pid] => 1 
            [total] => 3 
          ) 

        [2] => Array 
          ( 
            [path] => /var/www/html/company/pcntl/run.php 
            [pid] => 2 
            [total] => 3 
          ) 

      ) 
      */ 

      pcntl_signal(SIGCHLD, SIG_IGN); //Èç¹u¸¸½ø³Ì²»¹ØÐÄ×Ó½ø³Ìʲôʱºo½aÊø,×Ó½ø³Ì½aÊøºo£¬Äں˻a»ØÊÕ¡£ 
      foreach ($cmdArr as  $cmd) { 
        $pid = pcntl_fork();  //´´½¨×Ó½ø³Ì 
        //¸¸½ø³ÌºÍ×Ó½ø³Ì¶¼»aÖ´ÐÐÏÂÃae´uÂe 
        if ($pid == -1) { 
          //´iÎo´¦Ài£º´´½¨×Ó½ø³Ìʧ°Üʱ*µ»Ø-1. 
          die('could not fork'); 
        } else if ($pid) { 
          //¸¸½ø³Ì»aµÃµ½×Ó½ø³ÌºÅ£¬ËuÒÔÕaÀiÊǸ¸½ø³ÌÖ´ÐеÄÂß¼­ 
          //Èç¹u²»ÐeÒª×eÈu½ø³Ì£¬¶øÓÖÏeµÃµ½×Ó½ø³ÌµÄÍ˳o״̬£¬Ôo¿ÉÒÔ×¢Ê͵opcntl_wait($status)Ói¾a£¬»oд³É£º 
          pcntl_wait($status,WNOHANG); //µÈ´ý×Ó½ø³ÌÖжϣ¬*ÀÖ¹×Ó½ø³Ì³ÉΪ½(C)ʬ½ø³Ì¡£ 
        } else { 
          //×Ó½ø³ÌµÃµ½µÄ$pidΪ0, ËuÒÔÕaÀiÊÇ×Ó½ø³ÌÖ´ÐеÄÂß¼­¡£ 
          $path  = $cmd["path"]; 
          $pid = $cmd['pid'] ; 
          $total = $cmd['total'] ; 
          echo exec("/usr/bin/php {$path} {$pid} {$total}")."\n"; 
          exit(0) ; 
        } 
      } 
      ?> 

ʹÓÃPHPÕaeÕýµÄ¶a½ø³ÌÔËÐÐģʽ£¬ÊÊÓÃÓÚÊý¾Ý²É¼¯¡¢ÓʼþȺ¢¡¢Êý¾ÝÔ´¸uС¢tcpþÎñÆ÷µÈ»*½Ú¡£

PHPÓÐÒ»×e½ø³Ì¿ØÖƺ¯Êý(±aÒeʱÐeÒª ¨Cenable-pcntlÓeposixÀ(C)Õ¹)£¬Ê¹µÃphpÄÜÔÚnixϵͳÖÐʵÏÖ¸ucÒ»ÑuµÄ´´½¨×Ó½ø³Ì¡¢Ê¹ÓÃexecº¯ÊýÖ´ÐгÌÐo¡¢´¦ÀiÐźŵȹ¦ÄÜ¡£ PCNTLʹÓÃticksÀ´×÷ΪÐźŴ¦Ài»uÖÆ£¨signal handle callback mechanism£(C)£¬¿ÉÒÔ×iС³Ì¶ÈµØ½µµÍ´¦ÀiÒi²½Ê¼þʱµÄ¸ºÔØ¡£ºÎνticks£¿Tick ÊÇÒ»¸oÔÚ´uÂe¶ÎÖнaÊÍÆ÷ÿִÐÐ N ÌoµÍ¼¶Ói¾a¾Í»a¢ÉuµÄʼþ£¬Õa¸o´uÂe¶ÎÐeҪͨ¹ýdeclareÀ´Ö¸¶¨¡£

³£ÓõÄPCNTLº¯Êý
1. pcntl_alarm ( int $seconds )
ÉeÖÃÒ»¸o$secondsÃeºo*¢ËÍSIGALRMÐźŵļÆÊýÆ÷

2. pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls ] )
Ϊ$signoÉeÖÃÒ»¸o´¦Ài¸ÃÐźŵĻص÷º¯Êý¡£ÏÂÃaeÊÇÒ»¸o¸o5Ãe*¢ËÍÒ»¸oSIGALRMÐźţ¬²¢ÓÉsignal_handlerº¯Êý»ñÈ¡£¬È»ºo´oÓ¡Ò»¸o¡°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(;;) {
    }

    ?>

3. pcntl_exec ( string $path [, array $args [, array $envs ]] )
ÔÚµ±Ç°µÄ½ø³Ì¿Õ¼aÖÐÖ´ÐÐÖ¸¶¨³ÌÐo£¬ÀaËÆÓÚcÖеÄexec×aº¯Êý¡£Ëuνµ±Ç°¿Õ¼a£¬¼´ÔØÈeÖ¸¶¨³ÌÐoµÄ´uÂe¸²¸Çµoµ±Ç°½ø³ÌµÄ¿Õ¼a£¬Ö´ÐÐÍe¸Ã³ÌÐo½ø³Ì¼´½aÊø¡£


    <?php
    $dir = '/home/shankka/';
    $cmd = 'ls';
    $option = '-l';
    $pathtobin = '/bin/ls';

    $arg = array($cmd, $option, $dir);

    pcntl_exec($pathtobin, $arg);
    echo '123';  //²»»aÖ´Ðе½¸ÃÐÐ
    ?>

4. pcntl_fork ( void )
Ϊµ±Ç°½ø³Ì´´½¨Ò»¸o×Ó½ø³Ì£¬²¢ÇÒÏÈÔËÐи¸½ø³Ì£¬µ»ØµÄÊÇ×Ó½ø³ÌµÄPID£¬¿Ï¶¨´oÓÚÁa¡£ÔÚ¸¸½ø³ÌµÄ´uÂeÖпÉÒÔÓà pcntl_wait£¨&$status£(C)ÔÝÍ£¸¸½ø³ÌÖªµÀËuµÄ×Ó½ø³ÌÓе»ØÖµ¡£×¢Òa£º¸¸½ø³ÌµÄ×eÈuͬʱ»a×eÈu×Ó½ø³Ì¡£µ«ÊǸ¸½ø³ÌµÄ½aÊø²»Ó°Ïi×Ó½ø³ÌµÄÔËÐС£
¸¸½ø³ÌÔËÐÐÍeÁË»a½Ó×ÅÔËÐÐ×Ó½ø³Ì£¬Õaʱ×Ó½ø³Ì»a´ÓÖ´ÐÐpcntl_fork£¨£(C)µÄÄÇÌoÓi¾a¿ªÊ¼Ö´ÐУ¨°uÀ¨´Ëº¯Êý£(C)£¬µ«ÊÇ´ËʱËuµ»ØµÄÊÇÁa£¨´u±iÕaÊÇÒ»¸o×Ó½ø³Ì£(C)¡£ÔÚ×Ó½ø³ÌµÄ´uÂe¿eÖÐ×iºÃÓÐexitÓi¾a£¬¼´Ö´ÐÐÍe×Ó½ø³ÌºoÁ¢¼´¾Í½aÊø¡£ñÔoËu»aÓÖÖØÍ¿ªÊ¼Ö´ÐÐÕa¸o½Å±¾µÄijÐ(C)²¿Ö¡£

×¢ÒaÁ½µa£º

  1. ×Ó½ø³Ì×iºÃÓÐÒ»¸oexit£»Ói¾a£¬*ÀÖ¹²»±ØÒªµÄ³o´i£»
  2. pcntl_fork¼a×iºÃ²»ÒªÓÐÆaËuÓi¾a£¬ÀýÈ磺

    <?php
    $pid = pcntl_fork();
    //ÕaÀi×iºÃ²»ÒªÓÐÆaËuµÄÓi¾a
    if ($pid == -1) {
      die('could not fork');
    } else if ($pid) {
      // we are the parent
    pcntl_wait($status); //Protect against Zombie children
    } else {
      // we are the child
    }
    ?>

5. pcntl_wait ( int &$status [, int $options ] )
×eÈuµ±Ç°½ø³Ì£¬Ö»µ½µ±Ç°½ø³ÌµÄÒ»¸o×Ó½ø³ÌÍ˳o»oÕßÊÕµ½Ò»¸o½aÊøµ±Ç°½ø³ÌµÄÐźš£Ê¹ÓÃ$statusµ»Ø×Ó½ø³ÌµÄ״̬Âe£¬²¢¿ÉÒÔÖ¸¶¨µÚ¶þ¸o²ÎÊýÀ´ËµÃ÷ÊÇñÒÔ×eÈu״̬µ÷Óãº
×eÈu½Ê½µ÷Óõģ¬º¯Êýµ»ØֵΪ×Ó½ø³ÌµÄpid,Èç¹uûÓÐ×Ó½ø³Ìµ»ØֵΪ-1£»
Ç×eÈu½Ê½µ÷Ó㬺¯Êý»¹¿ÉÒÔÔÚÓÐ×Ó½ø³ÌÔÚÔËÐе«Ã»ÓнaÊøµÄ×Ó½ø³Ìʱµ»Ø0¡£

6. pcntl_waitpid ( int $pid , int &$status [, int $options ] )
¹¦ÄÜͬpcntl_wait£¬Çø±ðΪwaitpidΪµÈ´ýÖ¸¶¨pidµÄ×Ó½ø³Ì¡£µ±pidΪ-1ʱpcntl_waitpidÓepcntl_wait Ò»Ñu¡£ÔÚpcntl_waitºÍpcntl_waitpidÁ½¸oº¯ÊýÖеÄ$statusÖдaeÁË×Ó½ø³ÌµÄ״̬ÐÅÏ¢£¬Õa¸o²ÎÊý¿ÉÒÔÓÃÓÚ pcntl_wifexited¡¢pcntl_wifstopped¡¢pcntl_wifsignaled¡¢pcntl_wexitstatus¡¢ pcntl_wtermsig¡¢pcntl_wstopsig¡¢pcntl_waitpidÕaÐ(C)º¯Êý¡£
ÀýÈ磺


    <?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);
    }
    ?>

×Ó½ø³ÌÔÚÊa³ochild processµÈ×ÖÑuÖ®ºosleepÁË2Ãe²Å½aÊø£¬¶ø¸¸½ø³Ì×eÈu×ÅÖ±µ½×Ó½ø³ÌÍ˳oÖ®ºo²Å¼ÌÐøÔËÐС£

7. pcntl_getpriority ([ int $pid [, int $process_identifier ]] )
È¡µÃ½ø³ÌµÄÓÅÏȼ¶£¬¼´niceÖµ£¬Ä¬ÈÏΪ0£¬ÔÚÎҵIJaÊÔ»*¾³µÄlinuxÖУ¨CentOS release 5.2 (Final)£(C)£¬ÓÅÏȼ¶Îª-20µ½19£¬-20ΪÓÅÏȼ¶×i¸ß£¬19Ϊ×iµÍ¡££¨ÊÖ²aÖÐΪ-20µ½20£(C)¡£

8. pcntl_setpriority ( int $priority [, int $pid [, int $process_identifier ]] )
ÉeÖýø³ÌµÄÓÅÏȼ¶¡£

9. posix_kill
¿ÉÒÔ¸ø½ø³Ì*¢ËÍÐźÅ

10. pcntl_singal
ÓÃÀ´ÉeÖÃÐźŵĻص÷º¯Êý

µ±¸¸½ø³ÌÍ˳oʱ£¬×Ó½ø³ÌÈçºÎµÃÖª¸¸½ø³ÌµÄÍ˳o
µ±¸¸½ø³ÌÍ˳oʱ£¬×Ó½ø³ÌÒ»°a¿ÉÒÔͨ¹ýÏÂÃaeÕaÁ½¸o±È½Ï¼oµ¥µÄ½¨µÃÖª¸¸½ø³ÌÒѾ­Í˳oÕa¸oÏuÏ¢£º

µ±¸¸½ø³ÌÍ˳oʱ£¬»aÓÐÒ»¸oINIT½ø³ÌÀ´ÁiÑøÕa¸o×Ó½ø³Ì¡£Õa¸oINIT½ø³ÌµÄ½ø³ÌºÅΪ1£¬ËuÒÔ×Ó½ø³Ì¿ÉÒÔͨ¹ýʹÓÃgetppid()À´È¡µÃµ±Ç°¸¸½ø³ÌµÄpid¡£Èç¹uµ»ØµÄÊÇ1£¬±iÃ÷¸¸½ø³ÌÒѾ­±aΪINIT½ø³Ì£¬ÔoÔ­½ø³ÌÒѾ­ÍƳo¡£
ʹÓÃkillº¯Êý£¬ÏoÔ­Óеĸ¸½ø³Ì
¢ËÍ¿ÕÐźţ¨kill(pid, 0)£(C)¡£Ê¹ÓÃÕa¸o½¨¶Ôij¸o½ø³ÌµÄ´aeÔÚÐÔ½øÐмi²e£¬¶ø²»»aÕaeµÄ¢ËÍÐźš£ËuÒÔ£¬Èç¹uÕa¸oº¯Êýµ»Ø-1±iʾ¸¸½ø³ÌÒѾ­Í˳o¡£

³ýÁËÉÏÃaeµÄÕaÁ½¸o½¨Ía£¬»¹ÓÐÒ»Ð(C)ʵÏÖÉϱȽϸ´ÔӵĽ¨£¬±ÈÈ罨Á¢¹ÜµÀ»osocketÀ´½øÐÐʱʱµÄ¼a¿ØµÈµÈ¡£

PHP¶a½ø³Ì²É¼¯Êý¾ÝµÄÀý×Ó


    <?php
    /**
    * Project: Signfork: php¶aÏ߳̿a
    * File:  Signfork.class.php
    */

    class Signfork{
     /**
      * ÉeÖÃ×Ó½ø³ÌͨÐÅÎļþËuÔÚĿ¼
      * @var string
      */
     private $tmp_path='/tmp/';

    /**
     * SignforkÒýÇaeÖ÷Æo¶¯*½*¨
     * 1¡¢ÅжÏ$argÀaÐÍ,ÀaÐÍΪÊý×eʱ½«Öµ´«µÝ¸øÿ¸o×Ó½ø³Ì;ÀaÐÍΪÊýÖµÐÍʱ,´u±iÒª´´½¨µÄ½ø³ÌÊý.
     * @param object $obj Ö´ÐжÔÏo
     * @param string|array $arg ÓÃÓÚ¶ÔÏoÖеÄ__fork*½*¨ËuÖ´ÐеIJÎÊý
     * Èç:$arg,×Ô¶¯*Ö½aΪ:$obj->__fork($arg[0])¡¢$obj->__fork($arg[1])...
     * @return array *µ»Ø  array(×Ó½ø³ÌÐoÁÐ=>×Ó½ø³ÌÖ´Ðнa¹u);
     */
     public function run($obj,$arg=1){
      if(!method_exists($obj,'__fork')){
       exit("Method '__fork' not found!");
      }

      if(is_array($arg)){
       $i=0;
       foreach($arg as $key=>$val){
        $spawns[$i]=$key;
        $i++;
        $this->spawn($obj,$key,$val);
       }
       $spawns['total']=$i;
      }elseif($spawns=intval($arg)){
       for($i = 0; $i < $spawns; $i++){
        $this->spawn($obj,$i);
       }
      }else{
       exit('Bad argument!');
      }

      if($i>1000) exit('Too many spawns!');
       return $this->request($spawns);
      }

     /**
      * SignforkÖ÷½ø³Ì¿ØÖÆ*½*¨
      * 1¡¢$tmpfile ÅжÏ×Ó½ø³ÌÎļþÊÇ*ñ´aeÔÚ£¬´aeÔÚÔo×Ó½ø³ÌÖ´ÐÐÍe±Ï£¬²¢¶ÁÈ¡ÄÚÈÝ
      * 2¡¢$dataÊÕ¼¯×Ó½ø³ÌÔËÐнa¹u¼°Êý¾Ý£¬²¢ÓÃÓÚ×iÖÕ*µ»Ø
      * 3¡¢É¾³ý×Ó½ø³ÌÎļþ
      * 4¡¢ÂÖѯһ´Î0.03Ãe£¬Ö±µ½ËuÓÐ×Ó½ø³ÌÖ´ÐÐÍe±Ï£¬ÇaÀi×Ó½ø³Ì×ÊÔ´
      * @param string|array $arg ÓÃÓÚ¶ÔӦÿ¸o×Ó½ø³ÌµÄID
      * @return array *µ»Ø  array([×Ó½ø³ÌÐoÁÐ]=>[×Ó½ø³ÌÖ´Ðнa¹u]);
      */
      private function request($spawns){
       $data=array();
       $i=is_array($spawns)?$spawns['total']:$spawns;
       for($ids = 0; $ids<$i; $ids++){
        while(!($cid=pcntl_waitpid(-1, $status, WNOHANG)))usleep(30000);
        $tmpfile=$this->tmp_path.'sfpid_'.$cid;
        $data[$spawns['total']?$spawns[$ids]:$ids]=file_get_contents($tmpfile);
        unlink($tmpfile);
       }
       return $data;
      }

    /**
     * Signfork×Ó½ø³ÌÖ´ÐÐ*½*¨
     * 1¡¢pcntl_fork Éu³É×Ó½ø³Ì
     * 2¡¢file_put_contents ½«'$obj->__fork($val)'µÄÖ´Ðнa¹u´aeÈeÌض¨ÐoÁÐÃuÃuµÄÎı¾
     * 3¡¢posix_killɱËÀµ±Ç°½ø³Ì
     * @param object $obj    ´ýÖ´ÐеĶÔÏo
     * @param object $i        ×Ó½ø³ÌµÄÐoÁÐID£¬ÒÔ±aÓÚ*µ»Ø¶ÔӦÿ¸o×Ó½ø³ÌÊý¾Ý
     * @param object $param ÓÃÓÚÊaÈe¶ÔÏo$obj*½*¨'__fork'Ö´ÐвÎÊý
     */
     private function spawn($obj,$i,$param=null){
      if(pcntl_fork()===0){
       $cid=getmypid();
       file_put_contents($this->tmp_path.'sfpid_'.$cid,$obj->__fork($param));
       posix_kill($cid, SIGTERM);
       exit;
      }
     }
    }
    ?>

phpÔÚpcntl_fork()ºoÉu³ÉµÄ×Ó½ø³Ì(ͨ³£Îª½(C)ʬ½ø³Ì)±ØÐeÓÉpcntl_waitpid()º¯Êý½øÐÐ×ÊÔ´ÊÍÅ¡£µ«ÔÚ pcntl_waitpid()²»Ò»¶¨ÊÍŵľÍÊǵ±Ç°ÔËÐеĽø³Ì£¬Ò²¿ÉÄÜÊǹýÈ¥Éu³ÉµÄ½(C)ʬ½ø³Ì(ûÓÐÊÍÅ)£»Ò²¿ÉÄÜÊDz¢¢Ê±ÆaËu*ÃÎÊÕߵĽ(C)ʬ½ø³Ì¡£µ«¿ÉÒÔʹÓÃposix_kill($cid, SIGTERM)ÔÚ×Ó½ø³Ì½aÊøʱɱµoËu¡£

×Ó½ø³Ì»a×Ô¶¯¸´ÖƸ¸½ø³Ì¿Õ¼aÀiµÄ±aÁ¿¡£

PHP¶a½ø³Ì±a³ÌʾÀý2


    <?php
    //.....
    //ÐeÒª°²×°pcntlµÄphpÀ(C)Õ¹£¬²¢¼ÓÔØËu
    if(function_exists("pcntl_fork")){
      //Éu³É×Ó½ø³Ì
     $pid = pcntl_fork();
     if($pid == -1){
      die('could not fork');
     }else{
      if($pid){
       $status = 0;
       //×eÈu¸¸½ø³Ì£¬Ö±µ½×Ó½ø³Ì½aÊø£¬²»ÊʺÏÐeÒª³¤Ê±¼aÔËÐеĽű¾£¬¿ÉʹÓÃpcntl_wait($status, 0)ʵÏÖ*Ç×eÈuʽ
       pcntl_wait($status);
       // parent proc code
       exit;
      }else{
       // child proc code
       //½aÊøµ±Ç°×Ó½ø³Ì£¬ÒÔ*ÀÖ¹Éu³É½(C)ʬ½ø³Ì
       if(function_exists("posix_kill")){
        posix_kill(getmypid(), SIGTERM);
       }else{
        system('kill -9'. getmypid());
       }
       exit;
      }
     }
    }else{
      // ²»Ö§³Ö¶a½ø³Ì´¦ÀiʱµÄ´uÂeÔÚÕaÀi
    }
    //.....
    ?>
    Èç¹u²»ÐeÒª×eÈu½ø³Ì£¬¶øÓÖÏeµÃµ½×Ó½ø³ÌµÄÍ˳o״̬£¬Ôo¿ÉÒÔ×¢Ê͵opcntl_wait($status)Ói¾a£¬»oд³É£º

    <?php
    pcntl_wait($status, 1);
    //»o
    pcntl_wait($status, WNOHANG);
    ?>

ÔÚÉÏÃaeµÄ´uÂeÖУ¬Èç¹u¸¸½ø³ÌÍ˳o(ʹÓÃexitº¯ÊýÍ˳o»oredirect)£¬Ôo»aµ¼ÖÂ×Ó½ø³Ì³ÉΪ½(C)ʬ½ø³Ì(»a½»¸øinit½ø³Ì¿ØÖÆ)£¬×Ó½ø³Ì²»ÔÙÖ´ÐС£

½(C)ʬ½ø³ÌÊÇÖ¸µÄ¸¸½ø³ÌÒѾ­Í˳o,¶ø¸Ã½ø³ÌdeadÖ®ºoûÓнø³Ì½ÓÊÜ,¾Í³ÉΪ½(C)ʬ½ø³Ì.(zombie)½ø³Ì¡£Èκνø³ÌÔÚÍ˳oÇ°(ʹÓÃexitÍ˳o) ¶¼»a±a³É½(C)ʬ½ø³Ì(ÓÃÓÚ±£´ae½ø³ÌµÄ״̬µÈÐÅÏ¢)£¬È»ºoÓÉinit½ø³Ì½Ó¹Ü¡£Èç¹u²»¼°Ê±»ØÊÕ½(C)ʬ½ø³Ì£¬ÄÇôËuÔÚϵͳÖоͻaÕ¼ÓÃÒ»¸o½ø³Ì±iÏi£¬Èç¹uÕaÖÖ½(C)ʬ½ø³Ì¹ý¶a£¬×iºoϵͳ¾ÍûÓпÉÒÔÓõĽø³Ì±iÏi£¬ÓÚÊÇÒ²ÎÞ*¨ÔÙÔËÐÐÆaËuµÄ³ÌÐo¡£

*Ô¤À½(C)ʬ½ø³ÌÓÐÒÔϼ¸ÖÖ½¨£º**

1. ¸¸½ø³Ìͨ¹ýwaitºÍwaitpidµÈº¯ÊýʹÆaµÈ´ý×Ó½ø³Ì½aÊø£¬È»ºoÔÙÖ´Ðи¸½ø³ÌÖеĴuÂe£¬Õa»aµ¼Ö¸¸½ø³Ì¹ÒÆð¡£ÉÏÃaeµÄ´uÂe¾ÍÊÇʹÓÃÕaÖֽʽʵÏֵģ¬µ«ÔÚWEB»¾³Ï£¬Ëu²»ÊʺÏ×Ó½ø³ÌÐeÒª³¤Ê±¼aÔËÐеÄÇe¿o(»aµ¼Ö³¬Ê±)¡£
ʹÓÃwaitºÍwaitpid½¨Ê¹¸¸½ø³Ì×Ô¶¯»ØÊÕÆa½(C)ʬ×Ó½ø³Ì(¸u¾Ý×Ó½ø³ÌµÄµ»Ø״̬)£¬waitpidÓÃÓÚÁÙ¿ØÖ¸¶¨×Ó½ø³Ì£¬waitÊǶÔÓÚËuÓÐ×Ó½ø³Ì¶øÑÔ¡£
2. Èç¹u¸¸½ø³ÌºÜ棬ÄÇô¿ÉÒÔÓÃsignalº¯ÊýΪSIGCHLD°²×°handler£¬ÒoΪ×Ó½ø³Ì½aÊøºo£¬¸¸½ø³Ì»aÊÕµ½¸ÃÐźţ¬¿ÉÒÔÔÚhandlerÖе÷ÓÃwait»ØÊÕ
3. Èç¹u¸¸½ø³Ì²»¹ØÐÄ×Ó½ø³Ìʲôʱºo½aÊø£¬ÄÇô¿ÉÒÔÓÃsignal(SIGCHLD, SIG_IGN)֪ͨÄںˣ¬×Ô¼º¶Ô×Ó½ø³ÌµÄ½aÊø²»¸ÐÐËȤ£¬ÄÇô×Ó½ø³Ì½aÊøºo£¬Äں˻a»ØÊÕ£¬²¢²»ÔÙ¸ø¸¸½ø³Ì
¢ËÍÐźţ¬ÀýÈ磺


    <?php
    pcntl_signal(SIGCHLD, SIG_IGN);
    $pid = pcntl_fork();
    //....code
    ?>

4. »¹ÓÐÒ»¸o¼¼ÇÉ£¬¾ÍÊÇforkÁ½´Î£¬¸¸½ø³ÌforkÒ»¸o×Ó½ø³Ì£¬È»ºo¼ÌÐø¹¤×÷£¬×Ó½ø³ÌÔÙforkÒ»¸oËi½ø³ÌºoÍ˳o£¬ÄÇôËi½ø³Ì±»init½Ó¹Ü£¬Ëi½ø³Ì½aÊøºo£¬init»a»ØÊÕ¡£²»¹ý×Ó½ø³ÌµÄ»ØÊÕ»¹Òª×Ô¼º×o¡£ÏÂÃaeÊÇÒ»¸oÀý×Ó£º


    #include "apue.h"
    #include <sys/wait.h>

    int main(void){
    pid_t  pid;

    if ((pid = fork()) < 0){
      err_sys("fork error");
    } else if (pid == 0){   /**//* first child */
     if ((pid = fork()) < 0){
       err_sys("fork error");
     }elseif(pid > 0){
       exit(0);  /**//* parent from second fork == first child */
     }

     /**
      * We're the second child; our parent becomes init as soon
      * as our real parent calls exit() in the statement above.
      * Here's where we'd continue executing, knowing that when
      * we're done, init will reap our status.
      */
      sleep(2);
      printf("second child, parent pid = %d ", getppid());
      exit(0);
    }

    if (waitpid(pid, NULL, 0) != pid) /**//* wait for first child */
     err_sys("waitpid error");

    /**
     * We're the parent (the original process); we continue executing,
     * knowing that we're not the parent of the second child.
     */
     exit(0);
    }

ÔÚfork()/execve()¹ý³ÌÖУ¬¼ÙÉe×Ó½ø³Ì½aÊøʱ¸¸½ø³ÌÈÔ´aeÔÚ£¬¶ø¸¸½ø³Ìfork()֮ǰ¼Èû°²×°SIGCHLDÐźŴ¦Àiº¯Êýµ÷Óà waitpid()µÈ´ý×Ó½ø³Ì½aÊø£¬ÓÖûÓÐÏÔʽºoÂÔ¸ÃÐźţ¬Ôo×Ó½ø³Ì³ÉΪ½(C)ʬ½ø³Ì£¬ÎÞ¨Õý³£½aÊø£¬´Ëʱ¼´Ê¹ÊÇrootÉiÝkill-9Ò²²»ÄÜɱËÀ½(C)ʬ½ø³Ì¡£²¹¾È°i*¨ÊÇɱËÀ½(C)ʬ½ø³ÌµÄ¸¸½ø³Ì(½(C)ʬ½ø³ÌµÄ¸¸½ø³Ì±ØÈ»´aeÔÚ)£¬½(C)ʬ½ø³Ì³ÉΪ¡±¹Â¶u½ø³Ì¡±£¬¹ý¼Ì¸ø1ºÅ½ø³Ìinit£¬init»a¶¨ÆÚµ÷ÓÃwait»ØÊÕÇaÀiÕaÐ(C)¸¸½ø³ÌÒÑÍ˳oµÄ½(C)ʬ×Ó½ø³Ì¡£

ËuÒÔ£¬ÉÏÃaeµÄʾÀý¿ÉÒԸijɣº


    <?php
    //.....
    //ÐeÒª°²×°pcntlµÄphpÀ(C)Õ¹£¬²¢¼ÓÔØËu
    if(function_exists("pcntl_fork")){
     //Éu³ÉµÚÒ»¸o×Ó½ø³Ì
    $pid = pcntl_fork(); //$pid¼´Ëu²uÉuµÄ×Ó½ø³Ìid
    if($pid == -1){
     //×Ó½ø³Ìforkʧ°Ü
     die('could not fork');
    }else{
     if($pid){
      //¸¸½ø³Ìcode
      sleep(5); //µÈ´ý5Ãe
      exit(0); //»o$this->_redirect('/');
     }else{
      //µÚÒ»¸o×Ó½ø³Ìcode
      //²uÉuËi½ø³Ì
      if(($gpid = pcntl_fork()) < 0){ ////$gpid¼´Ëu²uÉuµÄËi½ø³Ìid
       //Ëi½ø³Ì²uÉuʧ°Ü
       die('could not fork');
      }elseif($gpid > 0){
       //µÚÒ»¸o×Ó½ø³Ìcode£¬¼´Ëi½ø³ÌµÄ¸¸½ø³Ì
       $status = 0;
       $status = pcntl_wait($status); //×eÈu×Ó½ø³Ì,²¢*µ»ØËi½ø³ÌµÄÍ˳o״̬£¬ÓÃÓÚ¼i²eÊÇ*ñÕý³£Í˳o
       if($status ! = 0) file_put_content('filename', 'Ëi½ø³ÌÒi³£Í˳o');
       //µÃµ½¸¸½ø³Ìid
       //$ppid = posix_getppid(); //Èç¹u$ppidΪ1Ôo±iʾÆa¸¸½ø³ÌÒѱaΪinit½ø³Ì£¬Ô­¸¸½ø³ÌÒÑÍ˳o
       //µÃµ½×Ó½ø³Ìid£ºposix_getpid()»ogetmypid()»oÊÇfork*µ»ØµÄ±aÁ¿$pid
       //killµo×Ó½ø³Ì
       //posix_kill(getmypid(), SIGTERM);
       exit(0);
      }else{ //¼´$gpid == 0
       //Ëi½ø³Ìcode
       //....
       //½aÊøËi½ø³Ì(¼´µ±Ç°½ø³Ì)£¬ÒÔ*ÀÖ¹Éu³É½(C)ʬ½ø³Ì
       if(function_exists('posix_kill')){
         posix_kill(getmypid(), SIGTERM);
       }else{
         system('kill -9'. getmypid());
       }
       exit(0);
      }
     }
    }
    }else{
     // ²»Ö§³Ö¶a½ø³Ì´¦ÀiʱµÄ´uÂeÔÚÕaÀi
    }
    //.....
    ?>

ÔoÑu²uÉu½(C)ʬ½ø³ÌµÄ
Ò»¸o½ø³ÌÔÚµ÷ÓÃexitÃuÁi½aÊø×Ô¼ºµÄÉuÃuµÄʱºo£¬ÆaʵËu²¢Ã»ÓÐÕaeÕýµÄ±»Ïu»Ù£¬¶øÊÇÁoÏÂÒ»¸o³ÆΪ½(C)ʬ½ø³Ì£¨Zombie£(C)µÄÊý¾Ý½a¹¹£¨ÏµÍ³µ÷ÓÃexit£¬ËuµÄ×÷ÓÃÊÇʹ½ø³ÌÍ˳o£¬µ«Ò²½o½oÏÞÓÚ½«Ò»¸oÕý³£µÄ½ø³Ì±a³ÉÒ»¸o½(C)ʬ½ø³Ì£¬²¢²»Äܽ«ÆaÍeÈ«Ïu»Ù£(C)¡£ÔÚLinux½ø³ÌµÄ״̬ÖУ¬½(C)ʬ½ø³ÌÊÇdz£ÌØÊaµÄÒ»ÖÖ£¬ËuÒѾ­ÅÆuÁ˼¸ºoËuÓÐÄÚ´ae¿Õ¼a£¬Ã»ÓÐÈκοÉÖ´ÐдuÂe£¬Ò²²»Äܱ»µ÷¶È£¬½o½oÔÚ½ø³ÌÁбiÖб£ÁoÒ»¸oλÖ㬼ÇÔظýø³ÌµÄÍ˳o״̬µÈÐÅÏ¢¹(C)ÆaËu½ø³ÌÊÕ¼¯£¬³ý´ËÖ®Ía£¬½(C)ʬ½ø³Ì²»ÔÙÕ¼ÓÐÈκÎÄÚ´ae¿Õ¼a¡£ËuÐeÒªËuµÄ¸¸½ø³ÌÀ´ÎªËuÊÕʬ£¬Èç¹uËuµÄ¸¸½ø³Ìû°²×°SIGCHLDÐźŴ¦Àiº¯Êýµ÷ÓÃwait»owaitpid()µÈ´ý×Ó½ø³Ì½aÊø£¬ÓÖûÓÐÏÔʽºoÂÔ¸ÃÐźţ¬ÄÇôËu¾ÍÒ»Ö±±£³Ö½(C)ʬ״̬£¬Èç¹uÕaʱ¸¸½ø³Ì½aÊøÁË£¬ÄÇôinit½ø³Ì×Ô¶¯»a½ÓÊÖÕa¸o×Ó½ø³Ì£¬ÎªËuÊÕʬ£¬Ëu»¹ÊÇÄܱ»Ça³ýµÄ¡£µ«ÊÇÈç¹uÈç¹u¸¸½ø³ÌÊÇÒ»¸oÑ­»*£¬²»»a½aÊø£¬ÄÇô×Ó½ø³Ì¾Í»aÒ»Ö±±£³Ö½(C)ʬ״̬£¬Õa¾ÍÊÇΪʲôϵͳÖÐÓÐʱ»aÓкܶaµÄ½(C)ʬ½ø³Ì¡£

ÈκÎÒ»¸o×Ó½ø³Ì(init³ýÍa)ÔÚexit()Ö®ºo£¬²¢*ÇÂiÉϾÍÏuʧµo£¬¶øÊÇÁoÏÂÒ»¸o³ÆΪ½(C)ʬ½ø³Ì(Zombie)µÄÊý¾Ý½a¹¹£¬µÈ´ý¸¸½ø³Ì´¦Ài¡£ÕaÊÇÿ¸o×Ó½ø³ÌÔÚ½aÊøʱ¶¼Òª¾­¹ýµÄ½×¶Î¡£Èç¹u×Ó½ø³ÌÔÚexit()Ö®ºo£¬¸¸½ø³ÌûÓÐÀ´µÃ¼°´¦Ài£¬ÕaʱÓÃpsÃuÁi¾ÍÄÜ¿´µ½×Ó½ø³ÌµÄ״̬ÊÇ¡±Z¡±¡£Èç¹u¸¸½ø³ÌÄܼ°Ê± ´¦Ài£¬¿ÉÄÜÓÃpsÃuÁi¾ÍÀ´²»¼°¿´µ½×Ó½ø³ÌµÄ½(C)ʬ״̬£¬µ«Õa²¢²»µÈÓÚ×Ó½ø³Ì²»¾­¹ý½(C)ʬ״̬¡£

Èç¹u¸¸½ø³ÌÔÚ×Ó½ø³Ì½aÊø֮ǰÍ˳o£¬Ôo×Ó½ø³Ì½«ÓÉinit½Ó¹Ü¡£init½«»aÒÔ¸¸½ø³ÌµÄÉi*ݶԽ(C)ʬ״̬µÄ×Ó½ø³Ì½øÐд¦Ài¡£

ÁiÍa£¬»¹¿ÉÒÔдһ¸ophpÎļþ£¬È»ºoÔÚÒÔºǫÐÎʽÀ´ÔËÐÐËu£¬ÀýÈ磺


    <?php
    //Action´uÂe
    public function createAction(){
      //....
      //½«argsÌae»»³ÉÒª´«¸øinsertLargeData.phpµÄ²ÎÊý£¬²ÎÊý¼aÓÿոñ¼a¸o
      system('php -f insertLargeData.php ' . ' args ' . '&');
      $this->redirect('/');
    }
    ?>

È»ºoÔÚinsertLargeData.phpÎļþÖÐ×oÊý¾Ý¿a²Ù×÷¡£Ò²¿ÉÒÔÓÃcronjob + phpµÄ*½Ê½ÊµÏÖ´oÊý¾ÝÁ¿µÄ´¦Ài¡£

Èç¹uÊÇÔÚÖÕ¶ËÔËÐÐphpÃuÁi£¬µ±Öն˹رպo£¬¸Õ¸ÕÖ´ÐеÄÃuÁiÒ²»a±»Ç¿Öƹرգ¬Èç¹uÄaÏeÈÃÆa²»ÊÜÖն˹رյÄÓ°Ïi£¬¿ÉÒÔʹÓÃnohupÃuÁiʵÏÖ£º


    <?php
    //Action´uÂe
    public function createAction(){
      //....
      //½«argsÌae»»³ÉÒª´«¸øinsertLargeData.phpµÄ²ÎÊý£¬²ÎÊý¼aÓÿոñ¼a¸o
      system('nohup php -f insertLargeData.php ' . ' args ' . '&');
      $this->redirect('/');
    }
    ?>

Äa»¹¿ÉÒÔʹÓÃscreenÃuÁi´uÌaenohupÃuÁi¡£

 相关文章:
PHP分页显示制作详细讲解
SSH 登录失败:Host key verification failed
获取IMSI
将二进制数据转为16进制以便显示
获取IMEI
文件下载
贪吃蛇
双位运算符
PHP自定义函数获取搜索引擎来源关键字的方法
Java生成UUID
发送邮件
年的日历图
提取后缀名
在Zeus Web Server中安装PHP语言支持
让你成为最历害的git提交人
Yii2汉字转拼音类的实例代码
再谈PHP中单双引号的区别详解
指定应用ID以获取对应的应用名称
Python 2与Python 3版本和编码的对比
php封装的page分页类完整实例