我正在写一个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. 多线程问题
- 8. 多线程问题
- 9. 多线程问题
- 10. 多线程线程切换问题
- 11. Java多线程问题
- 12. WPF和多线程问题
- 13. 多线程处理问题
- 14. 快速多线程问题
- 15. Ruby多线程问题
- 16. Java多线程问题.join()
- 17. 的java多线程问题
- 18. NHibernate的多线程问题
- 19. WPF MVVM多线程问题
- 20. 多线程速度问题
- 21. Watin多线程问题
- 22. boost :: dynamic_bitset多线程问题
- 23. 多线程性能问题
- 24. Java TCP多线程问题
- 25. JavaFX多线程问题
- 26. java多线程问题
- 27. NInject和多线程问题
- 28. BeginInvoke,EndInvoke多线程问题?
- 29. Ghostscript.net多线程问题
- 30. C++多线程问题
PHP是不是线程。除非您使用curl_multi *系列函数,否则您的curl请求将会阻塞,直到完成为止。 – meagar 2010-08-25 00:44:06
我最终使用了http://github.com/LionsAd/rolling-curl库来满足我的需求。没有进程,没有线程。 – Zero 2010-08-25 15:10:14