摘要:所以我們只說的多進程,至于多線程就暫時放到一邊兒。出來新進程則成為子進程,原進程則成為父進程,子進程擁有父進程的副本。在父進程中返回子進程的進程,在子進程內部本身返回數字。
[原文地址:https://blog.ti-node.com/blog...]
實際上PHP是有多線程的,只是很多人不常用。使用PHP的多線程首先需要下載安裝一個線程安全版本(ZTS版本)的PHP,然后再安裝pecl的pthread擴展。
實際上PHP是有多進程的,有一些人再用,總體來說php的多進程還算湊合,只需要在安裝PHP的時候開啟pcntl模塊(是不是跟UNIX中的fcntl有點兒.... ....)即可。在*NIX下,在終端命令行下使用php -m就可以看到是否開啟了pcntl模塊。
所以我們只說php的多進程,至于php多線程就暫時放到一邊兒。
注意:不要在apache或者fpm環境下使用php多進程,這將會產生不可預估的后果。
進程是程序執行的實例,舉個例子有個程序叫做 “ 病毒.exe ”,這個程序平時是以文件形式存儲在硬盤上,當你雙擊運行后,就會形成一個該程序的進程。系統會給每一個進程分配一個唯一的非負整數用來標記進程,這個數字稱作進程ID。當該進程被殺死或終止后,其進程ID就會被系統回收,然后分配給新的其余的進程。
說了這么多,這鬼東西有什么用嗎?我平時用CI、YII寫個CURD跟這個也沒啥關聯啊。實際上,如果你了解APACHE PHP MOD或者FPM就知道這些東西就是多進程實現的。以FPM為例,一般都是nginx作為http服務器擋在最前面,靜態文件請求則nginx自行處理,遇到php動態請求則轉發給php-fpm進程來處理。如果你的php-fpm配置只開了5個進程,如果處理任意一個用戶的請求都需要1秒鐘,那么5個fpm進程1秒中就最多只能處5個用戶的請求。所以結論就是:如果要單位時間內干活更快更多,就需要更多的進程,總之一句話就是多進程可以加快任務處理速度。
在php中我們使用pcntl_fork()來創建多進程(在*NIX系統的C語言編程中,已有進程通過調用fork函數來產生新的進程)。fork出來新進程則成為子進程,原進程則成為父進程,子進程擁有父進程的副本。這里要注意:
子進程與父進程共享程序正文段
子進程擁有父進程的數據空間和堆、棧的副本,注意是副本,不是共享
父進程和子進程將繼續執行fork之后的程序代碼
fork之后,是父進程先執行還是子進程先執行無法確認,取決于系統調度(取決于信仰)
這里說子進程擁有父進程數據空間以及堆、棧的副本,實際上,在大多數的實現中也并不是真正的完全副本。更多是采用了COW(Copy On Write)即寫時復制的技術來節約存儲空間。簡單來說,如果父進程和子進程都不修改這些 數據、堆、棧 的話,那么父進程和子進程則是暫時共享同一份 數據、堆、棧。只有當父進程或者子進程試圖對 數據、堆、棧 進行修改的時候,才會產生復制操作,這就叫做寫時復制。
在調用完pcntl_fork()后,該函數會返回兩個值。在父進程中返回子進程的進程ID,在子進程內部本身返回數字0。由于多進程在apache或者fpm環境下無法正常運行,所以大家一定要在php cli環境下執行下面php代碼。
第一段代碼,我們來說明在程序從pcntl_fork()后父進程和子進程將各自繼續往下執行代碼:
0 ){ echo "我是父親".PHP_EOL; } else if( 0 == $pid ) { echo "我是兒子".PHP_EOL; } else { echo "fork失敗".PHP_EOL; }
將文件保存為test.php,然后在使用cli執行,結果如下圖所示:
第二段代碼,用來說明子進程擁有父進程的數據副本,而并不是共享:
0 ){ $number += 1; echo "我是父親,number+1 : { $number }".PHP_EOL; } else if( 0 == $pid ) { $number += 2; echo "我是父親,number+2 : { $number }".PHP_EOL; } else { echo "fork失敗".PHP_EOL; }
第三段代碼,比較容易讓人思維混亂,pcntl_fork()配合for循環來做些東西,問題來了:會顯示幾次 “ 兒子 ”?
0 ){ // do nothing ... } else if( 0 == $pid ){ echo "兒子".PHP_EOL; } }
上面代碼執行結果如下:
仔細數數,竟然是顯示了7次 “ 兒子 ”。好奇怪,難道不是3次嗎?... ...
下面我修改一下代碼,結合下面的代碼,再思考一下為什么會產生7次而不是3次。
0 ){ // do nothing ... } else if( 0 == $pid ){ echo "兒子".PHP_EOL; exit; } }
執行結果如下圖所示:
前面強調過:父進程和子進程將繼續執行fork之后的程序代碼。這里就不解釋,實在想不明白的,可以動手自己畫畫思考一下。
為了避免寫成臭尾理論文兒,這里強行斷篇分割一下,下一章說僵尸進程和孤兒進程的一些恩怨情仇。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/29338.html
摘要:原文地址正如標題所言,顫顫抖抖開篇。于是只能是你自己,把單子上的個快遞逐次和收到的對比一遍,然后對比完畢后再把這個單子給了阿梅,然后阿梅繼續等。剃光頭前的阿梅,就是,不敢正眼看老板娘一眼。剃光頭后的阿梅,就是,可徒手接魔鬼隊的死亡之球。 [原文地址:https://blog.ti-node.com/blog...] 正如標題所言,顫顫抖抖開篇epoll。顫顫抖抖的原因大概也就是以前幾乎...
摘要:主進程退出子進程繼續執行給進程重新起個名字加入我們出個子進程就可以搞定這些任務,那么出個子進程,同時父進程要負責這個子進程的狀態等。 [原文地址:https://blog.ti-node.com/blog...] 干巴巴地叨逼叨了這么久,時候表演真正的技術了! 做個高端點兒的玩意吧,加入我們要做一個任務系統,這個系統可以在后臺幫我們完成一大波(注意是一大波)數據的處理,那么我們自然想到...
摘要:孤兒進程是指父進程在出子進程后,自己先完了。這個問題很尷尬,因為子進程從此變得無依無靠無家可歸,變成了孤兒。在中,父進程對子進程的狀態收集等是通過和等完成的。這個函數返回退出的子進程的進程或者失敗返回。 [原文地址:https://blog.ti-node.com/blog...] 實際上,你們一定要記住:PHP的多進程是非常值得應用于生產環境具備高價值的生產力工具。 但我認為在正式開...
閱讀 3017·2023-04-26 00:32
閱讀 498·2019-08-30 15:52
閱讀 2105·2019-08-30 15:52
閱讀 3347·2019-08-30 15:44
閱讀 3280·2019-08-30 14:09
閱讀 1416·2019-08-29 15:15
閱讀 3390·2019-08-28 18:12
閱讀 1074·2019-08-26 13:55