PHP Kontrol Süreç Kimliği

5 Cevap php

Bu i bir süre için merak ve bu konuda sormak karar verdik şeydir.

Biz mevcut komut işlem kimliği dönecektir fonksiyon getmypid () var. Fonksiyonunun bir tür gibi var mı

php checkifpidexists (?) Ben bir dahili bir değil, bazı toplu iş komut dosyası çözümü anlamına gelir.

Ve bir komut pid değiştirmek için bir yolu var mı?

Bazı açıklama:

Ben bu yüzden, tekrar çalıştırmak sahte cron işi Yüklü bir pid komut zaten çalışıyorsa görmek için olup olmadığını kontrol etmek istiyorsanız eğer olacaktır.

I pid değiştirmek istedim nedeni yüzden ben bu yüzden sadece 1 örnek aday olacağını pid yüzden bu script sadece o üzerinde çalıştırabilirsiniz böyle 60000 ve değer sabit kod gibi gerçekten yüksek bir şey için komut pid ayarlayabilirsiniz olduğunu

EDIT ----

Bu proplem ile başkasının yardımcı olmak için, ben bu sınıfı oluşturduk:

class instance {

    private $lock_file = '';
    private $is_running = false;

    public function __construct($id = __FILE__) {

    	$id = md5($id);

    	$this->lock_file = sys_get_temp_dir() . $id;

    	if (file_exists($this->lock_file)) {
    		$this->is_running = true;
    	} else {
    		$file = fopen($this->lock_file, 'w');
    		fclose($file);
    	}
    }

    public function __destruct() {
    	if (file_exists($this->lock_file) && !$this->is_running) {
    		unlink($this->lock_file);
    	}
    }

    public function is_running() {
    	return $this->is_running;
    }

}

ve bunu gibi kullanabilirsiniz:

$instance = new instance('abcd'); // the argument is optional as it defaults to __FILE__

if ($instance->is_running()) {
    echo 'file already running';	
} else {
    echo 'file not running';
}

5 Cevap

Linux olarak, / proc bakmak olacaktır.

return file_exists( "/proc/$pid" );

Windows Eğer () tasklist.exe shell_exec olabilir ve bu bir eşleştirme işlemi id bulur:

$processes = explode( "\n", shell_exec( "tasklist.exe" ));
foreach( $processes as $process )
{
     if( strpos( "Image Name", $process ) === 0
       || strpos( "===", $process ) === 0 )
          continue;
     $matches = false;
     preg_match( "/(.*?)\s+(\d+).*$/", $process, $matches );
     $pid = $matches[ 2 ];
}

Ben ne yapmak istediğiniz bir PID dosyası korumak olduğuna inanıyorum. Ben yazdım cinleri, onlar pid dosyasının dışına pid almak, / proc / $ pid olup olmadığını görmek için kontrol edin, bir pid dosyasının bir örneği için bakmak, bir yapılandırma dosyasını denetleyin ve değilse, pid silmek dosya.

   if( file_exists("/tmp/daemon.pid"))
   {
       $pid = file_get_contents( "/tmp/daemon.pid" );
       if( file_exists( "/proc/$pid" ))
       {
           error_log( "found a running instance, exiting.");
           exit(1);
       }
       else
       {
           error_log( "previous process exited without cleaning pidfile, removing" );
           unlink( "/tmp/daemon.pid" );
       }
   }
   $h = fopen("/tmp/daemon.pid", 'w');
   if( $h ) fwrite( $h, getmypid() );
   fclose( $h );

Süreç kimlikleri OS tarafından verilir ve bir süreç kimliği ayıramaz. Sen pid dosyasını saygı için daemon yazardı.

Bunu gerçekleştirmek için daha iyi bir yolu, bir pid ya da bir kilit dosyası kullanmak olacaktır. Basitçe, pid dosyasının varlığını kontrol gerekli oluşturun ve koşu pid ile doldurmak.

<?
  class pidfile {
    private $_file;
    private $_running;

    public function __construct($dir, $name) {
      $this->_file = "$dir/$name.pid";

      if (file_exists($this->_file)) {
        $pid = trim(file_get_contents($this->_file));
        if (posix_kill($pid, 0)) {
          $this->_running = true;
        }
      }

      if (! $this->_running) {
        $pid = getmypid();
        file_put_contents($this->_file, $pid);
      }
    }

    public function __destruct() {
      if ((! $this->_running) && file_exists($this->_file)) {
        unlink($this->_file);
      }
    }

    public function is_already_running() {
      return $this->_running;
    }
  }
?>

Aşağıdaki gibi ve kullanın:

<?
  $pidfile = new pidfile('/tmp', 'myscript');
  if($pidfile->is_already_running()) {
    echo "Already running.\n";
    exit;
  } else {
    echo "Started...\n";
  }
?>

Orada burada kontrol fazla hata değil, ama hızlı bir çalışma bu benim sistemde çalışır gösterir.

Hayır herhangi bir sürecin pid değiştiremezsiniz. Bu çekirdek tarafından atanan ve çekirdeğin veri yapılarının bir parçası olduğunu

Diğerleri söylediler, sen proses id değiştiremezsiniz - bu işletim sisteminin çekirdek tarafından atanan ve tamamen manged. Bu tabanlı komut satırı veya web sunucusu ise Ayrıca, dedi değil: bu ikincisi eğer sen bile script pid elde olmayabilir.

manual page for getmypid() "iyimser" kilitleme bazı örnekler içermektedir. Ben asla hiç paylaşılan / statik sınıflar ve böylece Singleton'un / kötüye kullanımı ile gerçek bir dişli bir ortam var bir asp.net web uygulaması seviyor yaklaşım gidiyor PHP gibi optimisitc sözcüğünü kullanın. Temelde seçeneği var:

  • Yere dosya sisteminde bir "kilit dosyası" dokunmak. Bu dosya varsa script o kontrol eder: o, sona erer, aksi takdirde, bu dosyaya dokunun ve işleme devam
  • Komut dosyası çalıştıran söylemek için bir veritabanı tabanlı bayrak ayarı. Yukarıdaki gibi, fakat çalışan bir komut dosyası işaretlemek için bir db tablo / alanını kullanın.

(Son adım kilit dosyası / db bayrağını kaldırmak olurdu gibi) Bunların ikisi de doğru sonlandırma komut güveniyor. Bir komut dosyası herhangi bir nedenle (veya makinenin kendisi) için çökerse, sen bayrağı kaldırmak için bir el düzenli-up süreci ile bırakılabilir. Bunun için kolay bir çözümdür, ama yaklaşımı "X daha eski ise, son çalıştırma mahvetmiş olmalı" keşfetmek için bir caddedir sonra keyfi ile, güncel damgalama kilit bakmak olacaktır.

Eğer pid'ler ile çalışma * nix araçları standardına erişmek verecek ters tırnakların (`) aracılığıyla kabuk komutlarına erişebilirsiniz bu da unutmayın.

Kaynak: http://www.php.net/manual/en/language.operators.execution.php