Spawn ve çocuk çıkabilirsiniz, böylece herhangi bir db-bilgi paylaşımı olmadan PHP sürecini ayırmak?

3 Cevap php

Ben MySQL masaya geçer ve çocuk süreçleri çoğaltılır bir "ebedi" süreci istiyoruz. Sahte kod:

while(true)
    $rows = SELECT * FROM workers
    foreach($rows as $row){
         DELETE $row->id
         spawn_child($row->id)
    }
    sleep(5)
}
function spawn_child($id){
     $pid = pcntl_fork()
     if($pid <0){
         //err
     }elseif($pid == 0){
         //child
         exec("worker_program $id");
         exit();
     }elseif($pid > 0){
         //parent
     }
 }

Sorun alt süreç worker_program ve çıkışların geri geldiğinde, görünüşte ortak mysql-kolu kapatır, bu nedenle ana süreç bir "Msql server went away"-hata alır olmasıdır.

Bunu nasıl çözerim? Bir tasarım hatası mı?

How do I spawn and detach a process in PHP, without sharing any db resources etc, so that the child is free to exit?

. Ben PDO kullanıyorum) yerine php bölmek arasında 'worker_program &' ile işçileri çağırarak, setsid ve yine forking, ama garip (tüm çalışmak için görünmüyor Ayrıca: (Ben denedim?. üzerinde php.net de çocuklar bu davranış Bu OSX ve PHP5.3 üzerinde (ve debian). bir hata olmadığını söylüyor.)

Ref.:

php.net / hata: "Parent process lost MySQLi connection after child process gone"

Update/workaround

Yani sonunda bu ile başa çıkmak için bir yol buldum. Ne işleri popen alt işlemleri yumurtlamaya kullanmaktır. Bu tamamen "taze" bir süreç gibi görünüyor bu şekilde herhangi bir hisse olmadan oluşturulur. Sonra çocuk forking ve kendini ayırma yapalım. Bu nedenle, ana işlemde, yerine pcntl_fork ya da exec,

$p = popen("worker_program $arg","r");
sleep(1); //give it time to detach (won't work otherwise. Any other ideas?)
pclose($p);

Ve sonra işçi programı:

#!/usr/bin/env php
<?php

//fully detach from parent, as proposed by the 'gurus'
//(Why can't this be done with only one fork?)
if(pcntl_fork()) {
    exit();
}
posix_setsid();
if(pcntl_fork()) {
    exit();
}
...

3 Cevap

Nasıl kalıcı bir MySQL bağlantısı kullanarak ilgili. Sen bitti biliyorum zaman ve kapanış.

$conn = new mysqli("p:".$dbhost, $dbuser, $dbpass, $dbname);

$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass,
    array(PDO::ATTR_PERSISTENT => true));

Nasıl çocuk yapılır, bu yüzden çocuk Çıkışta kapalı olmayacak zaman açıkça db kolu unset olur? Ebeveyn bu linki ele bulunuyor korumak gerekir, bu yüzden bağlantı kapatılmamış olabilir.

Bunların hiçbiri benim için çalıştı. Ben yaptım ...

// php execl type behaviour, execute and leave ...
// the args may be passed to $command or $args
// ekerner@ekerner.com.au
function execl($command, $args = array())
{
  $command = escapeshellarg($command);
  foreach ($args as $arg)
    $command .= ' ' . escapeshellarg($arg);
  exec($command . ' 2>/dev/null >&- /dev/null &');
}

Have fun, Eugene.