PHP asenkron kabuk exec

11 Cevap php

Ben bir kabuk betiği çağırmak gerekiyor ama çıkışı hakkında hiç umurumda değil bir PHP komut dosyası var. Kabuk komut soap görüşmeleri bir dizi yapar ve tamamlamak için yavaş, bu yüzden bir cevapta beklerken PHP isteğini yavaşlatmak istemiyorum. Aslında, PHP isteği Kabuk işlemi sonlandırılıyor çıkmak gerekir.

Ben çeşitli exec(), shell_exec(), pcntl_fork(), vb fonksiyonlar içine baktım, ama bunların hiçbiri tam olarak ne istediğinizi teklif gibi görünüyor. (Eğer onlar yapmak Veya, bu nasıl benim için açık değil.) Herhangi bir öneriniz?

11 Cevap

O "çıktı umurumda değil" ise, komut dosyasına exec & arka plan süreci ile birlikte adı edilemedi?

EDIT - Ne birleştiren @ AdamTheHut Bu yazı için yorumladı, size bir çağrı bu eklemek exec yapabilirsiniz:

" > /dev/null 2>/dev/null &"

Bu, her ikisi de yeniden yönlendirir stdio (birinci >) ve stderr (2>) /dev/null ve çalıştırmak background.

Orada aynı şeyi yapmak için başka yolları vardır, ama bu okumak için basit olduğunu.


Yukarıda çift yönlendirmek için bir alternatif:

" &> /dev/null &"

Gerçekten bağımsız bir süreç başlıyor gibi ben, bunun için at kullanılır.

<?php
    `echo "the command"|at now`;
?>

Linux üzerinde aşağıdakileri yapabilirsiniz:

$cmd = 'nohup nice -n 10 /usr/bin/php -c /path/to/php.ini -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & printf "%u" $!';
$pid = shell_exec($cmd);

Bu komut prompty de komutunu çalıştırın ve sonra sadece o amele sağlamak için> 0 için kontrol edebilirsiniz, hangi PID dönecektir.

Bu soru benzer: Does PHP have threading?

php-execute-a-background-process bazı iyi öneriler var. Ben benim oldukça iyi olduğunu düşünüyorum, ama ben önyargılı değilim :)

Linux, sen komutun sonunda bir işareti ekleyerek, yeni bir bağımsız iş parçacığı bir süreç başlayabilir

mycommand -someparam somevalue &

Windows'ta, "başlangıç" DOS komut kullanabilirsiniz

start mycommand -someparam somevalue

doğru yolu (!) bunu yapmak için için

  1. fork ()
  2. setsid ()
  3. execve ()

çatal, arama işlemi denilen biri tarafından değiştirilmesi anlatmak execve, bir usta bir (hiçbir ebeveyn) olmak için mevcut süreci anlatmak setsid. ebeveyn çocuğu etkileyen olmadan çıkmak böylece.

 $pid=pcntl_fork ();
 if($pid==0)
 {
   posix_setsid ();
   pcntl_exec($cmd,$args,$_ENV);
   // child becomes the standalone detached process
 }

 // parent's stuff
 exit();

Bu kullanmış ...

/** 
 * Asynchronously execute/include a PHP file. Does not record the output of the file anywhere.  
 * Relies on the PHP_PATH config constant.
 *
 * @param string $filename  file to execute
 * @param string $options   (optional) arguments to pass to file via the command line
 */ 
function asyncInclude($filename, $options = '') {
    exec(PHP_PATH . " -f {$filename} {$options} >> /dev/null &");
}

(Burada PHP_PATH bir const define('PHP_PATH', '/opt/bin/php5') ya da benzeri tanımlı)

Bu komut satırı üzerinden argümanlar geçer. , PHP bunları okumak görmek için argv.

Ben gerçekten benim için çalıştı bulundu tek yolu buydu:

shell_exec('./myscript.php | at now & disown')

Ayrıca cin veya cronjob ... #! / Usr / bin / php-q olarak php script çalıştırabilirsiniz

Adlandırılmış bir fifo kullanın.

#!/bin/sh
mkfifo trigger
while true; do
    read < trigger
    long_running_task
done

Eğer uzun süren görevi başlatmak için istediğiniz zaman sonra, sadece tetik dosyasına tıkanmasızdır (yeni satır yazmak.

Sürece girdi PIPE_BUF daha küçük ve tek bir write() operasyonu gibi, sen FIFOnun argümanları yazmak ve onları içinde $REPLY olarak göstermek var betik.

PHPClasses sitedeki başka bir çözüm vardır.

Ben bu yüzden çok web kullanışlı adapte ettik. Sen benim github içinde bulabilirsiniz (https://github.com/mmarquez/php-thread).

Bu çeşitli çocuk süreçlerin oluşturulmasını işleyebilir. Ben size yardımcı olabilir umuyoruz.