PHP多进程处理并行处理任务实例
生活随笔
收集整理的這篇文章主要介紹了
PHP多进程处理并行处理任务实例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2019獨角獸企業重金招聘Python工程師標準>>>
本文目的
本文通過例子講解linux環境下,使用php進行并發任務處理,以及如何通過pipe用于進程間的數據同步。寫得比較簡單,作為備忘錄。
PHP多進程
通過pcntl_XXX系列函數使用多進程功能。注意:pcntl_XXX只能運行在php CLI(命令行)環境下,在web服務器環境下,會出現無法預期的結果,請慎用!
管道PIPE
管道用于承載簡稱之間的通訊數據。為了方便理解,可以將管道比作文件,進程A將數據寫到管道P中,然后進程B從管道P中讀取數據。php提供的管道操作API與操作文件的API基本一樣,除了創建管道使用posix_mkfifo函數,讀寫等操作均與文件操作函數相同。當然,你可以直接使用文件模擬管道,但是那樣無法使用管道的特性了。
僵尸進程
子進程結束時,父進程沒有等待它(通過調用wait或者waitpid),那么子進程結束后不會釋放所有資源(浪費呀!),這種進程被稱為僵尸進程,他里面存放了子進程結束時的相關數據,如果僵尸進程過多,會占用大量系統資源(如內存),影響機器性能。
代碼
廢話少說直接上代碼
/** ? * this is a demo for php fork and pipe usage. fork use ? * to create child process and pipe is used to sychoroize ? * the child process and its main process. ? * @author bourneli ? * @date: 2012-7-6 ? */ 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)); // 模擬延時 ???????? $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 ); }ok,完畢,注釋寫的比較清除,執行結果如下:
轉載于:https://my.oschina.net/u/247923/blog/282663
總結
以上是生活随笔為你收集整理的PHP多进程处理并行处理任务实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JTable demo
- 下一篇: 9款基于CSS3 Transitions