2012-03-12 23 views
8

लेमे मेरे पास कोड के मूल विवरण देकर शुरू होता है। मैं एक मुख्य माता पिता प्रक्रिया के साथ शुरू (ध्यान दें:। मैं सादगी के लिए सभी कार्यों दिखा नहीं कर रहा हूँ मुझे जानते हैं अगर तुम मुझे जरूरत है किसी भी बिंदु पर विस्तार करने के लिए):बाद के pcntl_signal सिग्नल हैंडलर को लात मारना नहीं

declare(ticks=1); 
pcntl_signal(SIGHUP, array('forker', 'restartSignalHandler')); 
if(forker_is_not_running()){ 
    new Forker(); 
} 
class Forker { 
    private $active_forks = array(); 
    private $parent_pid = null; 

    public function __construct(){ 
     $this->parent_pid = getmypid(); 
     $this->create_fork(); 
     $this->wait_for_active(); 
    } 

    public function wait_for_active(){ 
     while(!empty($this->active_forks)){ 
      foreach($this->active_forks as $k=>$fork){ 
       if($this->fork_no_longer_running($fork)){ 
        unset($this->active_forks[$k]); 
       } 
      } 
     } 
    } 

    // Pseudo code 
    public function fork_no_longer_running($pid){ 
     // return true if 'ps -elf | grep $pid' doesn't returns only the grep command 
     // else return false (aka the fork is still running) 
    } 

    public function create_fork(){ 
     $pid = pcntl_fork(); 
     if($pid == -1){ 
      posix_kill($this->parent_pid, SIGTERM); 
     } else if($pid){ 
      // add the pid to the current fork 
      $this->active_forks[] = $pid; 
     } else { 
      // Run our process 
      pcntl_exec('/usr/bin/php', array('/domain/dev/www/index.php','holder','process')); 
      exit(0); 
     } 
    } 

    public function restartSignalHandler(){ 
     $forks = $this->active_forks; 
     foreach($forks as $pid){ 
      $this->create_fork(); 
      posix_kill($pid, SIGINT); 
     } 
    } 
} 

class holder { 
    public function process(){ 
     $x = new Processor(); 
    } 
} 

class Processor { 
    public function __construct(){ 
     pcntl_signal(SIGINT, array($this, "shutdownSignalHandler")); 
    } 
    public function shutdownSignalHandler(){ 
     echo "Shutting down"; 
     exit; 
    } 
} 

यहाँ है क्या हो रहा है:

  1. मैं अपने स्क्रिप्ट शुरू करने और मैं ठीक से प्रक्रियाओं (जैसे Parentpid: 2, childpid: 3) प्राप्त
  2. मैं तो माता-पिता एक SIGHUP संकेत भेजने और इसे ठीक से मारता है और एक नए बच्चे की प्रक्रिया शुरू (जैसे Parentpid: 2 , चाइल्डपिड: 4)
  3. मैं फिर पारे भेजता हूं एक दूसरा SIGHUP सिग्नल और यह ठीक से कोशिश करता है और एक नई बाल प्रक्रिया जोड़ता है, लेकिन यह दूसरे बच्चे के बच्चे को मारने से इंकार कर देता है। (जैसे Parentpid: 2, undyingchildpid: 4, newchildpid: 5)

Lemme पता है कि अगर अधिक जानकारी के की जरूरत है/मतलब नहीं है। मैं यह नहीं समझ सकता कि पहली बार यह सही ढंग से बच्चों को क्यों मार देगा, लेकिन दूसरी बार ऐसा नहीं होता है।

यहां तक ​​कि वेयरडर भाग यह है कि जब मैं इसे बदलता हूं तो मैं अपना पुनरारंभ करने वाला हैंडलर बदलता हूं ताकि वह बच्चे को सिगिनट से मारने की कोशिश करता रहता है, यह हर बार विफल रहता है, लेकिन जब मैं इसे सिगकिल कमांड भेजता हूं तो यह मारता है बाल प्रक्रिया:

if($time_passed > 60){ 
    posix_kill($pid, SIGKILL); 
} 

मुझे इसे ठीक से संभालने के लिए बच्चे को सिगिनट द्वारा मारने में सक्षम होने की आवश्यकता है। मैं सिर्फ सिगकिल नहीं करना चाहता हूं। क्या कोई कारण है कि सिगिनट के आसपास दूसरी बार क्यों काम नहीं करेगा, लेकिन सिगकिल होगा?

उत्तर

1

सबसे पहले, आपको कांटा की आवश्यकता नहीं है। आपका कोड बच्चे के अंदर एक निष्पादन करता है, आप मूल रूप से निष्पादन के दौरान निष्पादन चला सकते हैं, और ओएस आपके बच्चे को एक बच्चे के रूप में जन्म देगा। यदि आप फोर्क का उपयोग करना चाहते हैं, तो बस include निष्पादित करने के बजाए बच्चे में फ़ाइल।

public function create_fork(){ 
    //no need to actually fork! 
    pcntl_exec('/usr/bin/php', array('/domain/dev/www/index.php','holder','process')); 
} 

//if you want to fork, better do it like this : 


public function create_fork(){ 
    $pid = pcntl_fork(); 
    if($pid == -1){ 
     posix_kill($this->parent_pid, SIGTERM); 
    } else if($pid){ 
     // add the pid to the current fork 
     $this->active_forks[] = $pid; 
    } else { 
     // Run our process 
     include '/domain/dev/www/index.php'; 
     SomeClass::someMethod(); 
     exit(0); 
    } 
} 

इसके अलावा, कांटे का उपयोग करते समय, आपको बच्चों के लिए waitpid की आवश्यकता होती है। पर

//somewhere in a loop : 
$pidOfExittedChild = pcntl_waitpid (-1, $status, WNOHANG); 
if ($pidOfExittedChild) { 
    //a child has exitted, check its $status and do something 
} 

चेक अधिक: http://php.net/manual/en/function.pcntl-waitpid.php

तो, अपने कोड में आप कुछ तरह डालने की आवश्यकता