今天被問到一個問題,php如何開啟多進程才比較穩定。
php開啟多進程執行一個操作有哪些方法:
首先想到的是使用pcntl的fork
具體可以參考之前的文章:PHP的pcntl多進程
其次想到的方法是使用linux的crontab
有個php程序,內部實現大概是
<?php
$startTime = time();
while(1) {
if (time() - $startTime > 600) {
break;
}
// ... Do SomeThing
}
意思是這個程序會持續10分鍾,10分鍾循環做這同一個操作
然后開啟一個cron:
*/2 * * * * /usr/local/bin/php XXX.php
這個cron每兩分鍾跑一個前面的php程序
這樣就能保證同時會有5個程序在Do SomeThing。
還有想到的方法是使用php的exec函數
首先當然有個Do SomeThing的php程序:a.php
啟動一個php父進程,在程序中使用exec:
<?php
for($i = 0; $i < $count; $i++){
exec("nohup /user/local/bin/php a.php >> /dev/null &");
}
這個方法當然也有很多變種,比如
1 第二個循環啟動的程序使用shell來做
2 第一個Do SomeThing的函數使用上個方法的持續進程
有啥區別呢
第一種使用pcntl的方法,感覺起來子進程“是受控制”的
意思就是父進程可以獲取處理子進程的輸出信息,也可以等待子進程處理完以后做后續操作。
而后面兩種子進程是“不受控制”的。
PS:要想讓后面兩種子進程受控制,或許可以使用一些第三方存儲,比如日志,比如redis等。
第二種和第三種方法,cron+php的方法,有種好處是不會出現長時間貯存內存中的進程。
由於php的底層實現很有可能導致內存泄漏,所以一個“寫的不夠好”的PHP程序如果長時間一直運行,很有可能導致內存使用出現問題。所以不應該讓一個php程序“長時間運行”。
第二三種方法,一個程序運行完成之后就會立即結束進程,即使有內存泄漏也不會導致任何問題。所以比較讓人放心點。
PS:再說一下,方法一也不是必須要起常駐內存的進程,但往往我們做的時候會讓父進程常駐着。
還有啥呢,往往多進程的話要注意並發,可能會用到鎖之類的。因為一般要保證Do SomeThing的原子性才行。
方法二我們在線上大量使用了,並上redis的pop隊列操作,使用情況真是嘎嘎好用。
