標籤:style blog http color 使用 os io 資料
php多進程使用pcntl_*系列函數
自己目前就知道一個 pcntl_fork() ,產生子進程
<?php header("Content-type:text/html;Charset=UTF8"); /* echo ‘當前程式已經運行到此處!‘ . "\n"; $temp = 1; //開始分進程 $pid = pcntl_fork(); if($pid == -1) exit(‘程式出錯!‘); if($pid) { echo "我是父進程,當前temp的值為$temp\n"; $temp = 0; }else { sleep(1); if($temp == 0) echo "我是子進程,當前temp的值為$temp\n"; $temp = 1; } 運行結果: 當前程式已經運行到此處! 我是父進程,當前temp的值為1 說明: 執行不到子進程,父進程跟子進程基本上是同時執行的。而且程式只運行一次。所以只能執行父進程 */ /*--------------------------*/ /* //目前時間大於制定的時間時,給一個get值 if(time() - strtotime(‘2014/08/05 16:02:00‘)) { $_GET[‘a‘] = 1; } $temp = false; echo ‘當前程式已經運行到此處!‘ . "\n"; //開始分進程 $pid = pcntl_fork(); var_dump($_GET); echo "上面是當前get的值\n"; if($pid == -1) exit(‘程式出錯!‘); if($pid) { //父進程死迴圈監聽 do{ if(isset($_GET[‘a‘])) { $temp = true; }else{ echo "我是父進程,一直在迴圈運行\n"; echo date(‘Y-m-d H:i:s‘) . "\n"; } }while(true); }else { while($temp) { echo "我是子進程,父進程更改了temp的值,我開始執行了!"; $temp = false; } } 結果: 當前程式已經運行到此處! array(1) { ["a"]=> int(1) } 上面是當前get的值 array(1) { ["a"]=> int(1) } 上面是當前get的值 說明: $pid後程式分叉,後面的程式執行了2次, 但是get的值為true,所有父進程改變了temp的值, 但是同時子進程也運行了(temp的值在被父進程改變之前運行),所以子進程也不允許。 跟上面的列子類似 warning: 系統資源佔用大,跟上面的類似 */ /*--------網摘代碼 define("PC", 10); // 進程個數 define("TO", 4); // 逾時 define("TS", 4); // 事件跨度,用於類比任務延時 if (!function_exists(‘pcntl_fork‘)) { die("pcntl_fork not existing"); } // 建立管道 $sPipePath = "my_pipe.".posix_getpid(); if (!posix_mkfifo($sPipePath, 0666)) { die("create pipe {$sPipePath} error"); } // 類比任務並發 for ($i = 0; $i < PC; ++$i ) { $nPID = pcntl_fork(); // 建立子進程 if ($nPID == 0) { // 子進程過程 //sleep(rand(1,TS)); // 類比延時 sleep(10); $oW = fopen($sPipePath, ‘w‘); fwrite($oW, $i."\n"); // 當前任務處理完比,在管道中寫入資料 fclose($oW); exit(0); // 執行完後退出 } } // 父進程 $oR = fopen($sPipePath, ‘r‘); stream_set_blocking($oR, FALSE); // 將管道設定為非堵塞,用於適應逾時機制 $sData = ‘‘; // 存放管道中的資料 $nLine = 0; $nStart = time(); while ($nLine < PC && (time() - $nStart) < TO) { $sLine = fread($oR, 1024); if (empty($sLine)) { continue; } echo "current line: {$sLine}\n"; // 用於分析多少任務處理完畢,通過‘\n’標識 foreach(str_split($sLine) as $c) { if ("\n" == $c) { ++$nLine; } } $sData .= $sLine; } echo "Final line count:$nLine\n"; fclose($oR); unlink($sPipePath); // 刪除管道,已經沒有作用了 // 等待子進程執行完畢,避免殭屍進程 $n = 0; while ($n < PC) { $nStatus = -1; $nPID = pcntl_wait($nStatus, WNOHANG); if ($nPID > 0) { echo "{$nPID} exit\n"; ++$n; } } // 驗證結果,主要查看結果中是否每個任務都完成了 $arr2 = array(); foreach(explode("\n", $sData) as $i) {// trim all if (is_numeric(trim($i))) { array_push($arr2, $i); } } $arr2 = array_unique($arr2); if ( count($arr2) == PC) { echo ‘ok‘; } else { echo "error count " . count($arr2) . "\n"; var_dump($arr2); } */
以上是自己測試的代碼,基本沒有學到什麼有價值的東西。
網摘代碼的源地址:http://www.cnblogs.com/bourneli/archive/2012/07/06/2579893.html