Nasıl bir PHP uygulamalarında çoklu iş parçacığı kullanabilirsiniz

17 Cevap php

Ister gerçekten PHP bir çok iş parçacıklı modeli uygulanması, ya da sadece taklit gerçekçi bir yolu var mı. Lütfen biraz zaman size PHP yürütülebilir başka bir örneğini yükleyebilir ve diğer eşzamanlı işlemleri işlemek için işletim sistemini zorlayacağını öne sürüldü.

Bu sorun PHP içinde onu öldürmek için hiçbir yolu yoktur, çünkü PHP kodu PHP örneği yürütülmesi bittiğinde bellekte kalır olmasıdır. Birkaç konuları taklit Yani siz ne olacak nedir hayal edebiliyorum. Yani hala çok parçacığı yapılır veya PHP içinde etkili simüle edilebilir bir yol arıyorum. Herhangi bir fikir?

17 Cevap

PHP çoklu için yerleşik desteği vardır.

Gerçi John Lim tarafından yayınlanmıştır gibi bir yaklaşım kullanabilirsiniz:

http://phplens.com/phpeverywhere/?q=node/view/254

Bence çok sağlam, ama size multitasking biraz göze gerekir değil.

Multi-threading is possible in php

Evet multi-threading in PHP pthreads ile yapabilirsiniz

PHP DOC Gönderen

pthreads PHP kullanıcı-kara multi-threading sağlayan bir nesne Orientated API. Bu Web veya Konsolu hedefleyen çok iş parçacıklı uygulamaları oluşturmak için gereken tüm araçları içerir. PHP uygulamaları oluşturmak, okuma, yazma, yürütme ve lifler, İşçi ve Takılabilir ile senkronize edebilirsiniz.

Simple Test

#!/usr/bin/php
<?php
class AsyncOperation extends Thread {

    public function __construct($arg) {
        $this->arg = $arg;
    }

    public function run() {
        if ($this->arg) {
            $sleep = mt_rand(1, 10);
            printf('%s: %s  -start -sleeps %d' . "\n", date("g:i:sa"), $this->arg, $sleep);
            sleep($sleep);
            printf('%s: %s  -finish' . "\n", date("g:i:sa"), $this->arg);
        }
    }
}

// Create a array
$stack = array();

//Iniciate Miltiple Thread
foreach ( range("A", "D") as $i ) {
    $stack[] = new AsyncOperation($i);
}

// Start The Threads
foreach ( $stack as $t ) {
    $t->start();
}

?>

Ilk oynatım

12:00:06pm:     A  -start -sleeps 5
12:00:06pm:     B  -start -sleeps 3
12:00:06pm:     C  -start -sleeps 10
12:00:06pm:     D  -start -sleeps 2
12:00:08pm:     D  -finish
12:00:09pm:     B  -finish
12:00:11pm:     A  -finish
12:00:16pm:     C  -finish

İkinci Run

12:01:36pm:     A  -start -sleeps 6
12:01:36pm:     B  -start -sleeps 1
12:01:36pm:     C  -start -sleeps 2
12:01:36pm:     D  -start -sleeps 1
12:01:37pm:     B  -finish
12:01:37pm:     D  -finish
12:01:38pm:     C  -finish
12:01:42pm:     A  -finish

Real World Example

error_reporting(E_ALL);
class AsyncWebRequest extends Thread {
    public $url;
    public $data;

    public function __construct($url) {
        $this->url = $url;
    }

    public function run() {
        if (($url = $this->url)) {
            /*
             * If a large amount of data is being requested, you might want to
             * fsockopen and read using usleep in between reads
             */
            $this->data = file_get_contents($url);
        } else
            printf("Thread #%lu was not provided a URL\n", $this->getThreadId());
    }
}

$t = microtime(true);
$g = new AsyncWebRequest(sprintf("http://www.google.com/?q=%s", rand() * 10));
/* starting synchronized */
if ($g->start()) {
    printf("Request took %f seconds to start ", microtime(true) - $t);
    while ( $g->isRunning() ) {
        echo ".";
        usleep(100);
    }
    if ($g->join()) {
        printf(" and %f seconds to finish receiving %d bytes\n", microtime(true) - $t, strlen($g->data));
    } else
        printf(" and %f seconds to finish, request failed\n", microtime(true) - $t);
}

Threading stok PHP mevcut değildir, ancak eşzamanlı programlama uyumsuz çağrı HTTP istekleri ile mümkündür.

Curl zaman aşımı ayarı, birbirleri ile ilişkili olmak istiyorum işlemler için aynı session_id kullanarak 1'e set ile, aşağıda benim örnekte olduğu gibi oturum değişkenleri ile iletişim kurabilirsiniz. Bu yöntem ile bile tarayıcınızı kapatabilirsiniz ve eşzamanlı süreci hala sunucuda var.

Böyle doğru oturum kimliğini doğrulamak unutmayın:

http://localhost/test/verifysession.php?sessionid = [doğru id]

startprocess.php

$request = "http://localhost/test/process1.php?sessionid=".$_REQUEST["PHPSESSID"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_exec($ch);
curl_close($ch);
echo $_REQUEST["PHPSESSID"];

process1.php

set_time_limit(0);

if ($_REQUEST["sessionid"])
   session_id($_REQUEST["sessionid"]);

function checkclose()
{
   global $_SESSION;
   if ($_SESSION["closesession"])
   {
       unset($_SESSION["closesession"]);
       die();
   }
}

while(!$close)
{
   session_start();
   $_SESSION["test"] = rand();
   checkclose();
   session_write_close();
   sleep(5);
}

verifysession.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
var_dump($_SESSION);

closeprocess.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
$_SESSION["closesession"] = true;
var_dump($_SESSION);

Eğer iplik olamaz da, php proses kontrolü bir ölçüde var. Burada yararlı olan iki fonksiyon setleri:

Process control functions http://www.php.net/manual/en/ref.pcntl.php

POSIX functions http://www.php.net/manual/en/ref.posix.php

Sen pcntl_fork ile süreci çatal olabilir - Çocuğun PID dönen. Sonra o PID'nin despose için posix_kill kullanabilirsiniz.

Yani bir üst süreç öldürmek eğer bir sinyal ölmek için söylüyorum çocuk süreç gönderilmesi gerektiğini söyledi. Php kendisi bu tanıma değilse bunu yönetmek için bir işlevi kayıt ve pcntl_signal kullanarak temiz bir çıkış yapabilir.

neden popen kullanmak değil mi?

for ($i=0; $i<10; $i++) {
    // open ten processes
    for ($j=0; $j<10; $j++) {
        $pipe[$j] = popen('script2.php', 'w');
    }

    // wait for them to finish
    for ($j=0; $j<10; ++$j) {
        pclose($pipe[$j]);
    }
}

Sen parçacığı taklit olabilir. PHP popen (veya proc_open) üzerinden arka plan işlemleri çalıştırabilirsiniz. Bu işlemler stdin ve stdout üzerinden ile tebliğ edilebilir. Tabii bu işlemler kendilerini bir php program olabilir. Muhtemelen alırsınız olarak yakındır.

Bir komut satırı komut dosyası (örneğin komut satırı php gibi) çalıştırmak için () exec kullanabilir, ve boru bir dosyaya çıktı eğer script bitirmek için komut beklemek olmaz.

Ben oldukça php CLI sözdizimi hatırlamak değil, ama böyle bir şey isterdim:

exec('/path/to/php -f '/path/to/file.php' | '/path/to/output.txt');

Ben epeyce hosting sunucuları exec () güvenlik nedenleriyle varsayılan olarak devre dışı, ama bir cami olabilir düşünüyorum.

Yapmanız çalıştığınız ne bağlı olarak da bunu başarmak için curl_multi kullanabilirsiniz.

Ben bu şekilde eski olduğunu biliyorum, ama http://phpthreadlib.sourceforge.net/ bakmak olabilir

Bu çift yönlü arası iplik iletişimi destekleyen ve aynı zamanda (yetimleri önlenmesi) çocuk konuları öldürülmesi için korumaları yerleşik gelmiştir.

Bu eski bir soru olduğunu biliyorum ama insanlar aramak için, bir PECL uzantısı burada bulunur, şimdi PHP çoklu iş parçacığı yeteneği verir C yazdı https://github.com/krakjoe/pthreads var

Multi-Threading PHP mümkün değildir.

Eğer önermek gibi Ancak, simüle edilebilir. I this article üzerinde ortaya çıkardı. Ama çoklu ihtiyaç şahsen eğer, ben size yanlış yazılım yığınını kullanarak ve belki bu tür bir şey için biraz daha güçlü ve uygun bir şey gerekir derim.

Onun sadece güncellemeleri veya plan aktivitesi / kontrolleri vb varsa, bir cron görevi yoluyla çalıştırabilir. Eğer geçerli önerileri yapmak için onun zor, çözmek isteyen vardır sorun hakkında daha fazla bilmeden.

Eğer seçenek olabilir:

  1. multi_curl
  2. Bir aynı sistem komutunu kullanabilirsiniz
  3. İdeal senaryo C dilinde bir parçacığı işlevi oluşturmak ve PHP / configure derleme vardır. Şimdi bu fonksiyonu PHP fonksiyonu olacaktır.

Nasıl pcntl_fork hakkında?

Örnekler için bizim manuel sayfasını kontrol: PHP pcntl_fork

Konu ile evreleri PECL uzantısı ile mümkün olmaktadır

http://www.php.net/manual/en/book.pthreads.php

Bir web sunucusu ortamında alışkanlık iş pcntl_fork ise "güvenli mod" Bu durumda sadece PHP CLI sürümünde çalışacak, açık var.

Exec i pencerelerde aşağıdaki kullanılan windows ortamında benim için asenkron olarak çalıştı ve ;) cazibe gibi çalıştı olmadı ama ben bir şey kaçırmış olabilir

$script_exec = "c:/php/php.exe c:/path/my_ascyn_script.php";

pclose(popen("start /B ". $script_exec, "r"));

Çok iş parçacığı aynı anda birden fazla görevleri veya işlemleri yapmak demektir, php çoklu ulaşmak için doğrudan bir yol olmasına rağmen biz, aşağıdaki kodu kullanarak php bu elde edebilirsiniz ama biz bir şekilde takip ederek, hemen hemen aynı sonuçları elde edebilirsiniz.

chdir(dirname(__FILE__));  //if you want to run this file as cron job
 for ($i = 0; $i < 2; $i += 1){
 exec("php test_1.php $i > test.txt &");
 //this will execute test_1.php and will leave this process executing in the background and will go         

 //to next iteration of the loop immediately without waiting the completion of the script in the   

 //test_1.php , $i  is passed as argument .

}

Test_1.php

$conn=mysql_connect($host,$user,$pass);
$db=mysql_select_db($db);
$i = $argv[1];  //this is the argument passed from index.php file
for($j = 0;$j<5000; $j ++)
{
mysql_query("insert  into  test   set

                id='$i',

                comment='test',

                datetime=NOW() ");

}

Bu şekilde size php çoklu elde edebilirsiniz böylece, bu aynı anda iki kez test_1.php yürüteceğini ve her iki işlem aynı anda arka planda çalışacaktır.

Bu adam gerçekten iyi bir iş yapmış Multithreading in php