本文地址php
參考文檔html
分享提綱:linux
1. 概述算法
2.安裝(只支持Linux)ubuntu
3. 代碼實驗多進程pcntl_fork數組
4. 具體解釋bash
PHP有個pcntl_fork的函數能夠實現多進程,但要加載pcntl拓展,並且只有在linux下才能編譯這個拓展,有時間在ubuntu下玩了下。微信
2.1) 首先在ubuntu下編譯pcntl.so,個人ubuntu下找不到pcntl的包,因而函數
建立一個文件夾下載了整個PHP包,在裏面找到了pcntl包運行以下命令post
# mkdir php # cd php # apt-get source php5 # cd php5-(WHATEVER_RELEASE)/ext/pcntl # phpize # ./configure (注一) # make # make install
phpize 命令是用來準備 PHP 外掛模塊的編譯環境的。
成功的安裝將創建 extname.so 並放置於 PHP 的外掛模塊目錄中 (預設存放於 /usr/lib/php/modules/ 內) 。
須要調整 php.ini,加入 extension=extname.so 這一行以後才能使用此外掛模塊。
1 <?php 2 //測試php的多進程 3 4 while(1)//循環採用3個進程 5 {/*{{{*/ 6 //declare(ticks=1); 7 $bWaitFlag= FALSE; // 是否等待進程結束 8 //$bWaitFlag = TRUE; // 是否等待進程結束 9 $intNum= 3; // 進程總數 10 $pids= array(); // 進程PID數組 11 for($i= 0; $i<$intNum; $i++) 12 { 13 $pids[$i] = pcntl_fork();// 產生子進程,並且從當前行之下開試運行代碼,並且不繼承父進程的數據信息 14 /*if($pids[$i])//父進程 15 { 16 //echo $pids[$i]."parent"."$i -> " . time(). "\n"; 17 } 18 */ 19 if($pids[$i] == -1) 20 { 21 echo"couldn't fork". "\n"; 22 } 23 elseif(!$pids[$i]) 24 { 25 sleep(1); 26 echo"\n"."第".$i."個進程 -> ". time(). "\n"; 27 //$url=" 抓取頁面的例子 28 //$content = file_get_contents($url); 29 //file_put_contents('message.txt',$content); 30 //echo "\n"."第".$i."個進程 -> " ."抓取頁面".$i."-> " . time()."\n"; 31 exit(0);//子進程要exit不然會進行遞歸多進程,父進程不要exit不然終止多進程 32 } 33 if($bWaitFlag) 34 { 35 pcntl_waitpid($pids[$i], $status, WUNTRACED);echo"wait $i -> ". time() . "\n"; 36 } 37 } 38 sleep(1); 39 }/*}}}*/
保存爲fork.php 在命令行運行 php fork.php
運行結果:
pcntl函數還有一些功能沒實驗,例如進程狀態,根據相應狀態進行一些處理,運用多進程能夠增長處理數據的效
率。在網上看到的fork的解釋:
fork以後,操做系統會複製一個與父進程徹底相同的子進程,雖然說是父子關係,可是在操做系統看來,他們更像兄弟關係,這2個進程共享代碼空間,但 是數據空間是互相獨立的,子進程數據空間中的內容是父進程的完整拷貝,指令指針也徹底相同,但只有一點不一樣,若是fork成功,子進程中fork的返回值 是0,父進程中fork的返回值是子進程的進程號,若是fork不成功,父進程會返回錯誤。
能夠這樣想象,2個進程一直同時運行,並且步調一致,在fork以後,他們分別做不一樣的工做,也就是分岔了。這也是fork爲何叫fork的緣由。
至於那一個最早運行,可能與操做系統有關,並且這個問題在實際應用中並不重要,若是須要父子進程協同,能夠經過原語的辦法解決。
----------------------------------------------
fork前父進程的東西子進程能夠繼承,而在fork後子進程沒有任何和父進程的繼承關係了。在子進程裏建立的東西是子進程的,在父進程建立的東西是父進程的。能夠徹底當作兩個進程。
----------------------------------------------
在程序段裏用了fork();以後程序出了分岔,派生出了兩個進程。具體哪一個先運行就看該系統的調度算法了。
在這裏,咱們能夠這麼認爲,在運行到」pid=fork();」時系統派生出一個跟主程序如出一轍的子進程。該進程的」pid=fork();」一句中 pid獲得的就是子進程自己的pid;子進程結束後,父進程的」pid=fork();」中pid獲得的就是父進程自己的pid。所以改程序有兩行輸出。
----------------------------------------------
fork()函數複製了當前進程的PCB,並向父進程返回了派生子進程的pid。並且根據上面」corand」兄的提示,父子進程並行,打印語句的 前後徹底看系統的調度算法。打印的內容控制則靠pid變量來控制。由於咱們知道fork()向父進程返回了派生子進程的pid,是個正整數;而派生子進程 的pid變量並無被改變。這一區別使得咱們看到了他們的不一樣輸出。
----------------------------------------------
1,派生子進程的進程,即父進程,其pid不變;2,對子進程來講,fork返回給它0,但它的pid絕對不會是0;之因此fork返回0給它,是由於它隨時能夠調用getpid()來獲取本身的pid;3,fork以後父子進程除非採用了同步手段,不然不能肯定誰先運行,也不能肯定誰先結束。認爲子進程結束後父進程才從fork返回的,這是不對的,fork不是這樣的,vfork才這樣。