2012-01-26 27 views
17

我有一些代碼是有點像這樣:調用在後臺線程/進程的功能(分叉)

($i=0; $i < 100; $i++) 
{ 
    do ($foo[$i]); 
} 

以上是一個耗時的任務,我希望能夠創建一個功能,並調用它兩次類似下面

function wrapper($start;$end) 
{ 
    ($i=$start; $i < $end; $i++) 
    { 
     do ($foo[$i]); 
    } 
} 
//have both of these run in parallel 
wrapper(0,50); 
wrapper(51,100); 

我看着Gearman的,但我不能使用它,因爲我不能安裝的Gearman服務器(因爲我是一個共享的服務器上)。似乎實現這一目標的方式將是分叉。我試着讀了很多,但文檔和支持很少。任何幫助/線框代碼將不勝感激。

要定義我的問題,我怎樣才能調用wrapper()傳遞參數,以便它在子進程中執行。另外,重要的是我可以註冊一個回調函數。

其他詳細信息:PHP 5.3,在Linux服務器上運行。腳本由cgi-fcgi執行。

我想這是我應該如何產生一個子進程,但我怎樣才能使用它來產生多個子進程?我該如何註冊一個回調函數?

$pid = pcntl_fork(); 

if ($pid == -1) {   
    // Fork failed    
    exit(1); 
} else if ($pid) { 
    // The parent process 
    //should I repeat this same code here to spawn another child process? 

} else { 
    // the child process 
    //can I call wrapper from here and will it run in this child process? 

回答

9

從 「都鐸巴爾布的專業博客」
http://blog.motane.lu/2009/01/02/multithreading-in-php/

require_once('Thread.php'); 

// test to see if threading is available 
if(! Thread::isAvailable()) { 
    die('Threads not supported'); 
} 

// function to be ran on separate threads 
function paralel($_limit, $_name) { 
    for ($index = 0; $index < $_limit; $index++) { 
     echo 'Now running thread ' . $_name . PHP_EOL; 
     sleep(1); 
    } 
} 

// create 2 thread objects 
$t1 = new Thread('paralel'); 
$t2 = new Thread('paralel'); 

// start them 
$t1->start(10, 't1'); 
$t2->start(10, 't2'); 

// keep the program running until the threads finish 
while($t1->isAlive() && $t2->isAlive()) { 

} 

Download Thread.php

+0

謝謝。這看起來像一個輝煌的包裝。我正在查看代碼 – xbonez

+1

您引用的鏈接還指出,使用空循環來檢查線程是否存活是不好的,因爲它會耗盡您的所有CPU。你應該在循環中加入睡眠。 – Kelvin

+0

@Kelvin,更好的解決方案是爲庫實現'join'功能,應該相當簡單。 –

2

如果你使用Linux,你可以在命令行的優勢,做

public function newWrapperInstance($start,$end){ 
    exec('bash -c "exec nohup setsid php-cli yourFile.php '.$start.' '.$end.' > /dev/null 2>&1 &"'); 
} 

這將在後臺創建一個新的PHP實例,並將它自己從主線程中的exec函數中分離出來。

警告: 唯一的缺點是,你無法控制這些線程創建後的功能。