我正在寫一個php cron作業,使用curl讀取數以千計的提要/網頁並將內容存儲在數據庫中。如何限制線程的數量,比如說6?即使我需要掃描數以千計的提要/網頁,但我只想在任何時候只有6個捲曲線程處於活動狀態,這樣我的服務器和網絡就不會陷入困境。我可以在Java中使用wait,notify,notifyall方法輕鬆地完成Object。我應該建立自己的信號量還是php提供任何內置函數?php多線程問題
php多線程問題
回答
首先,PHP沒有線程,但它確實有過程控制: http://php.net/manual/en/book.pcntl.php
我已經建立了圍繞這些函數的類來幫助我的多工藝要求。
我處於類似的情況。我正在記錄從cron開始的進程及其狀態。我正在從一個相關的cron工作中檢查他們。
EDIT(詳細信息):
在我的項目我都記錄到數據庫的關鍵變化。如果變更符合行動標準,則可採取行動。所以我正在做的與你不同。但是,也有一些相似之處。
當我分叉一個新的進程,我輸入它的PID在數據庫表。然後下一次cron作業開始時,它所做的一部分工作就是檢查進程是否已正確完成,然後在該數據庫表中將該作業標記爲已完成。
你不會提供關於你的項目的很多細節。所以我只是拋出一個建議:
- 數據庫表包含您要下載的資源的URL。
- 另一張表包含正在運行的進程的pid。
- 每小時運行一個cron作業將通過該表並下載資源並將其存儲在數據庫中。但是,首先檢查pid表是否有完整/死/正在運行的進程,並相應地執行。在這裏,您可以限制您的流程爲6.
根據您的項目大小,這可能看起來像是過度殺人。不過,我已經考慮了很長時間了,我想跟蹤所有這些分叉進程。分叉可能是有風險的業務,並且可能導致系統資源過載 - 從經驗上講);
我很想聽聽其他技術。
感謝您的快速回答。如何在6個進程中同步計數器?兩個進程不應該嘗試同時更新計數器。 – Zero 2010-08-25 01:10:36
我已經給答案添加了一些細節。我不知道你的項目結構如何,所以我不能確定這是否適合你,但我希望它有幫助。 – 2010-08-25 03:29:24
從我的答覆在PHP using proc_open so that it doesn't wait for the script it opens (runs) to finish?
我的一些代碼,當我與proc_open
發揮各地我曾與proc_close(10〜30秒),所以我只是用殺進程的問題linux命令殺人
curl有時候會在各種服務器(ubuntu,centos)上凍結我,但並不是所有的服務器上,所以我殺掉任何需要40秒的「子」進程,因爲通常腳本最多需要10秒鐘,而是重做工作,而不是等待一分鐘左右,因爲捲曲不會凍結。
$options=array();
$option['sleep-after-destroy']=0;
$option['sleep-after-create']=0;
$option['age-max']=40;
$option['dir-run']=dirname(__FILE__);
$option['step-sleep']=1;
$option['workers-max']=6;
$option['destroy-forcefull']=1;
$workers=array();
function endAWorker($i,$cansleep=true) {
global $workers;
global $option;
global $child_time_limit;
if(isset($workers[$i])) {
@doE('Ending worker [['.$i.']]'."\n");
if($option['destroy-forcefull']==1) {
$x=exec('ps x | grep "php check_working_child.php '.$i.' '.$child_time_limit.'" | grep -v "grep" | grep -v "sh -c"');
echo 'pscomm> '.$x."\n";
$x=explode(' ',trim(str_replace("\t",' ',$x)));
//print_r($x);
if(is_numeric($x[0])) {
$c='kill -9 '.$x[0];
echo 'killcommand> '.$c."\n";
$x=exec($c);
}
}
@proc_close($workers[$i]['link']);
unset($workers[$i]);
}
if($cansleep==true) {
sleep($option['sleep-after-destroy']);
}
}
function startAWorker($i) {
global $workers;
global $option;
global $child_time_limit;
$runcommand='php check_working_child.php '.$i.' '.$child_time_limit.' > check_working_child_logs/'.$i.'.normal.log';
doE('Starting [['.$i.']]: '.$runcommand."\n");
$workers[$i]=array(
'desc' => array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", 'check_working_child_logs/'.$i.'.error.log', "a")
),
'pipes' => null,
'link' => null,
'start-time' => mktime()
);
$workers[$i]['link']=proc_open(
$runcommand,
$workers[$i]['desc'],
$workers[$i]['pipes'],
$option['dir-run']
);
sleep($option['sleep-after-create']);
}
function checkAWorker($i) {
global $workers;
global $option;
$temp=proc_get_status($workers[$i]['link']);
if($temp['running']===false) {
doE('Worker [['.$i.']] finished'."\n");
if(is_file('check_working_child_logs/'.$i.'.normal.log') && filesize('check_working_child_logs/'.$i.'.normal.log')>0) {
doE('--------'."\n");
echo file_get_contents('check_working_child_logs/'.$i.'.normal.log');
doE('-------'."\n");
}
endAWorker($i);
} else {
if($option['age-max']>0) {
if($workers[$i]['start-time']+$option['age-max']$v) {
endAWorker($i,false);
}
@doE('Done killing workers.'."\n");
}
register_shutdown_function('endAllWorkers');
while(1) {
$step++;
foreach($workers as $index=>$v) {
checkAWorker($index);
}
if(count($workers)==$option['workers-max']) {
} elseif(count($workers)$option['workers-max']) {
$wl=array_keys($workers);
$wl=array_pop($wl);
doE('Killing worker [['.$wl.']]');
endAWorker($wl[0]);
}
}
並創建一個名爲「check_working_child.php」來完成所有的工作文件,第一個參數將是實例號,第二個時間限制 php check_working_child.php 5 60
意味着你是第5子和被允許運行60秒
如果上面的代碼不運行讓我知道,我會使用pastebin或其他東西發佈它...
- 1. PHP 7中的多線程問題
- 2. 多線程問題
- 3. 多線程問題
- 4. 多線程問題
- 5. 多線程問題
- 6. 多線程問題
- 7. iPhone「多線程」問題
- 8. 多線程處理問題
- 9. QObject(QPlainTextEdit)&多線程問題
- 10. Twilio問題與多線程
- 11. 快速多線程問題
- 12. 黑莓多線程問題
- 13. Java多線程問題
- 14. WPF和多線程問題
- 15. ActivityWeel多線程問題
- 16. C++多線程問題
- 17. Java多線程問題
- 18. Java多線程問題.join()
- 19. 多線程的Java問題
- 20. Java多線程問題
- 21. FMDB與多線程問題
- 22. C#多線程問題
- 23. 多線程速度問題
- 24. 基本多線程問題
- 25. Ruby多線程問題
- 26. java多線程問題
- 27. WPF MVVM多線程問題
- 28. python多線程問題
- 29. java編程和java單線程多線程問題(單線程與多線程)
- 30. Java - 線程太多的多線程問題
PHP是不是線程。除非您使用curl_multi *系列函數,否則您的curl請求將會阻塞,直到完成爲止。 – meagar 2010-08-25 00:44:06
我最終使用了http://github.com/LionsAd/rolling-curl庫來滿足我的需求。沒有進程,沒有線程。 – Zero 2010-08-25 15:10:14